【问题标题】:Create an instance of an object C++创建对象 C++ 的实例
【发布时间】:2021-07-22 02:46:49
【问题描述】:

我最近学习了 C++,但我在某些方面遇到了问题,因为我习惯了 Java,而且我不确定我是否以正确的方式做事。

我有一个文本文件,其中行的结构是这样的

C;101;1;1;4;10;
H;102;9;0;1;8;2
C;103;9;9;2;5;
C;104;0;9;3;8;

;是分隔符

C 用于检查是否为 Crawler(H 用于检查是否为 Hopper),然后是 id、position、directions(1-4)、size 和 alive(0/1) )

我有一个抽象的 Bug 类,然后我有一个 Crawler 和 Hopper 类,它们都继承自 Bug 类。

这是我的 Bug 类

class Bug
{
public:
    int id;
    pair<int, int> position;
    int direction;
    int size;
    bool alive;
    list<pair<int, int>> path;
    virtual void move() {}
    bool isWayBlocked() {}


    Bug(string type, int id, pair <int, int> position, int direction, int size, bool alive)
    {
        type = type;
        id = id;
        position = position;
        direction = direction;
        size = size;
        alive = alive;
    };
};

这里是爬虫类

class Crawler : public Bug
{
public:
    Crawler(int id, pair <int, int> position, int direction, int size)
        : Bug("Crawler", id, position, direction, size, alive)
    {
    }



};

这是我尝试创建 Crawler 对象实例的示例:

Bug* bugPtr;
        if (bugType == "C") {
            bugPtr = new Crawler(bugID, { xPos,yPos }, direction, size);
            //Crawler* CrawlerBugPointer = new Crawler(bugID, { xPos,yPos }, direction, size);
        }

我能够轻松地从文本文件中读取并存储变量,但是当我开始调试 bugPtr 中的所有字段时说 0,我怀疑我以完全错误的方式处理事情并且没有构建抽象类和继承类正确,谁能指出我做错了什么?任何帮助将不胜感激。

【问题讨论】:

标签: c++ class inheritance constructor abstract-class


【解决方案1】:

编译器应该为您的构造函数中的每一行生成一个警告,“可能没有效果的表达式”(或类似的)。阅读警告 - 它们很有用。

Bug(string type, int id, pair <int, int> position, int direction, int size, bool alive)
    {
        this->type = type;
        this->id = id;
        this->position = position;
        this->direction = direction;
        this->size = size;
        this->alive = alive;
    };

虽然 C++ 不需要在任何地方荒谬地使用 this,但在您的情况下,这是必要的,因为您已为构造函数参数提供与字段相同的名称。当你输入类似

id = id;

您的意思是,“在此范围内查找名称为 id 的变量,并将其值分配给自身。”什么都不做,这就是为什么您的所有字段都保留为默认值的原因。说this.id 的意思是,“找到名称为id 的类字段并将本地id 的值分配给它。”

【讨论】:

  • 非常感谢,我之前有 this.id,但它给出了错误,我在 Java 中一直使用 this.id,但实际上并不知道它的含义,感谢您的提示。
  • @Gabriel 不用担心,很高兴它有所帮助。您会发现,虽然 C++ 在许多情况下大部分看起来像 Java,但它们是非常不同的语言。一个方面的专业知识并不容易转化为另一个方面。如果您打算将这些错误存储在数组或向量中,请查看“c++ 对象切片”。
  • 我最后一次知道。 type 不是 C++ 中的保留字。而且这个初始化真的应该用一个初始化列表来完成。
  • @PeteBecker 我删除了type 评论。我觉得修改 OP 的构造函数是一个更清晰的解释,因为他们才刚刚开始使用该语言。初始化器列表没有性能优势;这只是方便。
  • 当类型具有非平凡的默认构造函数时,会有性能优势。当然,如果一个类型没有默认构造函数,它必须在初始化列表中初始化。更不用说初始化列表适当地处理这些重复的名称。初学者应该总是使用初始化列表。
【解决方案2】:

这样做的方法是使用初始化列表:

Bug(string type, int id, pair <int, int> position, int direction, int size, bool alive)
: type(type), id(id), position(position), direction(direction), size(size), alive(alive)
{ }

原始代码的问题是名称隐藏。在构造函数主体中,type = type 只是将名为 type 的参数的值分配给名为 type 的参数。它不会改变名为type 的成员的值。

但是在初始化列表中,在像type(type) 这样的条目中,第一个type 是成员的名称,第二个type 是参数的名称。所以成员得到了参数值,一切都很好。

您应该始终在构造函数中使用初始化列表。除了允许重复名称(如果这是您喜欢的话;许多程序员不这样做)之外,当您拥有具有更复杂初始化的数据成员时,它们会更有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多