将派生类变量添加到向量<baseclass>

时间:2016-03-07 22:12:12

标签: c++ vector

我正在学习一门新的语言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个未解析的外部

1 个答案:

答案 0 :(得分:2)

你可能碰到的第一个意想不到的令人讨厌的是

static vector<class Command> cmds;

这表示vector的静态Command。它没有为它分配任何空间,所以在其中一个CPP文件中,Command.cpp看起来像逻辑位置,你必须为吸盘分配存储

vector<Command> Command::cmds;

您不必撰写class CommandCommand是一个类隐含的类。但是,由于您打算使用Command的子项打包此向量,您可能需要

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

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

否则,您会获得Commandthe 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的一些解读:

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?