我正在学习一门新的语言C ++,其中包含来自Java not JavaScript
的知识。
我正在尝试使用派生类Command
创建一个名为CmdHelp
的Parent类。
在java中,我会创建一个名为abstract class
的{{1}},并将类Command.java
扩展为CmdHelp.java
,并在Command
的构造函数中生成静态CmdHelp.java
内的ArrayList<Command>
会像这样自我添加。
Command.java
这是Java,我正在尝试将其镜像到C ++中。当我在public CmdHelp() {
// Set protected variables here like label, usage, and description for the CmdHelp class.
cmds.add(this);
}
头文件中创建static vector<class Command>
变量,然后在Command.h
构造函数中创建了<{1}}变量时,
CmdHelp.cpp
似乎没有将实例添加到矢量列表中。 Bellow是我的所有C ++代码和文件。
的main.cpp
CmdHelp::CmdHelp() {
cmds.push_back((Command) *this);
}
Command.h
#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.cpp
#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();
};
CmdHelp.h
#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.cpp
#include "Command.h"
class CmdHelp: public Command {
public:
CmdHelp();
void run();
};
请帮助我,它会给出这些奇怪的错误。抱歉,如果这是超级简单的,我找不到解决方案,因为我不知道这甚至叫什么?这只是我学习Java 5年的第一周C ++。请做Java引用,以便我更容易理解。
谢谢。
以下是我的错误:
1&gt; CmdHelp.obj:错误LNK2001:未解析的外部符号“public:static class std :: vector&gt; Command :: cmds”(?cmds @ Command @@ 2V?$ vector @ PEAVCommand @@ V?$ allocator @PEAVCommand @@@ STD @@@ STD @@ A)
1&gt; Command.obj:错误LNK2001:未解析的外部符号“public:static class std :: vector&gt; Command :: cmds”(?cmds @ Command @@ 2V?$ vector @ PEAVCommand @@ V?$ allocator @PEAVCommand @@@ STD @@@ STD @@ A)
1&gt; C:\ Users \ Dennis \ Documents \ Projects \ CPPTutorial \ CPPTutorial \ x64 \ Debug \ CPPTutorial.exe:致命错误LNK1120:1个未解析的外部
答案 0 :(得分:2)
你可能碰到的第一个意想不到的令人讨厌的是
static vector<class Command> cmds;
这表示vector
的静态Command
。它没有为它分配任何空间,所以在其中一个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 Guards。你可能只是留下了这些,但不要。 #include
基本上意味着“在编译之前将命名文件粘贴到此处”。 Include Guards可以防止同一个文件被多次包含,并对无限包含循环,重复定义和其他错误造成严重破坏。
以下是关于Include Guard的一些解读:
如果还有更多问题,你必须列出你所得到的“奇怪错误”。
喔。还有一个java到c ++的东西。在java中,除非final
,否则一切都是虚拟的。我认为这是final
。我做完Java以来已经有一段时间了。在C ++中,除非你说它,否则什么都不是虚拟的。这意味着你因为没有为Command
声明虚拟析构函数而闯入析构函数的肮脏。
virtual ~ Command()
{
// does nothing
}
没有它,错误的析构函数或者不够的析构函数就会运行。
using namespace std;
很糟糕。标题非常糟糕:Why is "using namespace std" considered bad practice?