2016-03-07 60 views
0

我正在学习一门新的语言C++,其中使用了从Java not JavaScript使用的知识。 我试图用派生类CmdHelp来创建一个名为Command的父类。 在java中我会做一个abstract class称为Command.java,使类CmdHelp.java扩展到Command,并在CmdHelp.java构造我将有Command.java内的静态ArrayList<Command>,将增加它的自我是这样。将派生类变量添加到向量中<BaseClass>

public CmdHelp() { 
    // Set protected variables here like label, usage, and description for the CmdHelp class. 
    cmds.add(this); 
} 

这是Java,我试图把它镜像到C++。当我在Command.h头文件中创建一个static vector<class Command>变量,然后在CmdHelp.cpp构造,并没有

CmdHelp::CmdHelp() { 
    cmds.push_back((Command) *this); 
} 

它似乎并没有实例添加到向量列表。 Bellow是我所有的C++代码和文件。

的main.cpp

#include <iostream> 
#include <string> 
#include <fstream> 
#include <vector> 
#include "Command.h" 

using namespace std; 

int main() { 
    cout << "Initiated Command Line:" << endl; 
    while (true) { 
     cout << "> "; 
     string input = ""; 
     cin >> input; 
     bool found = Command::checkCommand(input); 
     if (found) { 
      Command::getCommand(input).run(); 
     } 
     else { 
      Command::printNotFound(); 
     } 
    } 
    return 0; 
} 

Command.h

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

class Command { 
public: 
    Command(); 
    // VARIABLES // 
    string label; 
    string usage; 
    string description; 
    // STATIC VARIABLES // 
    static vector<class Command> cmds; 
    // SETTER FUNCTIONS // 
    void setLabel(string); 
    void setUsage(string); 
    void setDescription(string); 
    // GETTER FUNCTIONS // 
    string getLabel(); 
    string getUsage(); 
    string getDescription(); 
    // INHERIT FUNCTIONS // 
    virtual void run(); // trying to make this function an "abstract" function like I would in Java. 
    // STATIC FUNCTIONS // 
    static Command getCommand(string); 
    static bool checkCommand(string); 
    static void printNotFound(); 
}; 

Command.cpp

#include "Command.h" 
#include <iostream> 
#include <string> 

using namespace std; 

Command::Command() { 
} 

// SETTER FUNCTIONS // 
void Command::setLabel(string label) { 
    Command::label = label; 
} 

void Command::setUsage(string usage) { 
    Command::usage = usage; 
} 

void Command::setDescription(string description) { 
    Command::description = description; 
} 

// GETTER FUNCTIONS // 
string Command::getLabel() { 
    return label; 
} 
string Command::getUsage() { 
    return usage; 
} 
string Command::getDescription() { 
    return description; 
} 

void Command::run() {} 

// STATIC FUNCTIONS // 
Command Command::getCommand(string label) { 
    for (int i = 0; i < cmds.size(); i++) { 
     if (cmds[i].getLabel() == label) { 
      return cmds[i]; 
     } 
    } 
    return Command(); 
} 
bool Command::checkCommand(string label) { 
    for (int i = 0; i < cmds.size(); i++) { 
     if (cmds[i].getLabel() == label) { 
      return true; 
     } 
    } 
    return false; 
} 
void Command::printNotFound() { 
    cout << "Command not found! Type \"help\"!" << endl; 
} 

CmdHelp.h

#include "Command.h" 

class CmdHelp: public Command { 
public: 
    CmdHelp(); 
    void run(); 
}; 

CmdHelp.cpp

#include "CmdHelp.h" 
#include <iostream> 
#include <string> 

using namespace std; 

CmdHelp::CmdHelp() { 
    setLabel("HELP"); 
    setUsage("/help"); 
    setDescription("Shows the help screen!"); 
    cmds.push_back((Command) *this); 
} 

void CmdHelp::run() { 
    cout << cmds[0].getLabel() << endl; 
} 

请帮我它给了这些奇怪的错误。对不起,如果这是超简单的,我找不到解决方案,因为我不知道这是甚么称呼?这只是我第一个C++的一周,当我了解Java 5年。请做Java引用,这样我可以更容易理解。

谢谢。

这里是我的错误:

1> CmdHelp.obj:错误LNK2001:解析外部符号? “市民:静态类的std ::矢量>命令:: CMDS”(CMDS @命令@@ 2V $ vector @ PEAVCommand @@ V $ $ allocator @ PEAVCommand @@@ std @@@ std @@ A)

1> Command.obj:error LNK2001:无法解析的外部符号“public:static class std :: vector> Command :: cmds“(?cmds @ Command @@ 2V?$ vector @ PEAVCommand @@ V?$ allocator @ PEAVCommand @@@ std @@@ std @@ A)

1> C:\ Users \ Dennis \ Documents \ Projects \ CPPTutorial \ CPPTutorial \ x64 \ Debug \ CPPTutorial.exe:致命错误LNK1120:1无法解析的外部

+1

是的,你提到的Java,但这并没有使这是一个Java问题,事实上,它不是,所以我已经删除了你的[tag:java]标签,以避免任何混乱。 –

+0

不要试图在C++中模仿Java,它最终会变得非常糟糕。不要以为C++中的类似构造会做它们在Java中所做的事情,它会以糟糕的方式结束。不要以为你可以使用C++编写代码,因为你知道Java,它会很糟糕的结束。回到你的书,忘记你对Java的所有知识,并开始阅读关于C++的知识。 – SergeyA

+0

谢谢我只是“抹去”我的Java经验,只练习C++,所以我可以得到jist。 – DennisOfficial

回答

2

意外讨厌你可能已经跨越运行的第一位是

static vector<class Command> cmds; 

这是说有一种Command个静态vector。它不会为它分配任何空间,所以在CPP文件中的一个,Command.cpp貌似合理的地方,你必须与

vector<Command> Command::cmds; 

的吸盘分配存储你不必写class Command,班级隐含Command为班级。但既然你打算包用Command儿童这一载体,你可能想

static std::vector<std::unique_ptr<Command>> cmds; 

vector<std::unique_ptr<Command>> Command::cmds; 

否则你得到的Command向量和the children you store will get sliced.

Documentation on std::unique_ptr.

你可以使用

static std::vector<Command*> cmds; 

但是,当您从cmds中删除命令并退出程序时,这会给您留下一大堆内存,需要进行清理。在Java之后,C++不会清理干净。

接下来的一点是包括卫兵。你可能已经离开了这些,但不要#include基本上是指“在编译之前将指定的文件粘贴在这里”。包含防御功能可防止同一个文件被多次包含,并对无限包含循环,重复定义和其他不良内容造成严重破坏。

这里是关于include防范一些阅读:

Wikipedia page

C++ #include guards

而且,如果有更多的问题,你必须列出你在说什么“奇怪的错误”。

哦。一个更多的Java到C++的东西。在java中,一切都是虚拟的,除非final。我认为这是final。自从我完成Java以来​​已经有一段时间了。在C++中,没有什么是虚拟的,除非你这么说。这意味着你可能会因为没有为Command声明虚拟析构函数而陷入破坏者的混乱。

virtual ~ Command() 
{ 
    // does nothing 
} 

如果没有它,错误的析构函数或者不足以运行。

using namespace std;不好。这是非常糟糕的标题:Why is "using namespace std" considered bad practice?

+0

我仍然收到相同的错误。它不会告诉我它刚刚说的错误是在exe文件中。 – DennisOfficial

+0

这是因为链接器不知道行。当连接器开始执行它的工作时,它正在处理编译对象,并且名称存在于对象文件中,或者不存在。你在Command.cpp中放置了'vector Command :: cmds;'吗? – user4581301