【问题标题】:C++ fill array with objects derived from array typeC++ 用从数组类型派生的对象填充数组
【发布时间】:2011-04-20 01:40:01
【问题描述】:

在 C++ 中,我有一个指向 Player 对象的指针数组,并希望用 Fickle 对象填充它,其中 Fickle 是从 Player 派生的类。这是因为我想要一个通用的 Player 数组,我可以填充来自不同类的不同对象,这些对象都派生自 Player 类。

我该怎么做?

我创建了一个指向 Player 对象的指针数组

Player ** playerArray;

然后将数组初始化为一定的大小

playerArray = new Player *[numPlayersIn];

但是由于某种原因,以下内容不起作用:

playerArray[i] = new Fickle(0);

如何用 Fickle 对象填充 playerArray(Fickel 是从 Player 派生的类)?

谢谢。

更新:

我收到错误消息(在 Eclipse IDE 中):

expected ';' before 'Fickle'

我认为这可能与 Fickle 的定义有关。

Fickle.hpp 文件包含:

#pragma once
#include "player.hpp";

class Fickle: public Player {
public:
    // constructor
    Fickle(int initChoice){
        choice = initChoice;
    }
}

这样没问题还是有问题?

Player 类头文件有:

class Player {
private:

public:
    int getChoice();
int choice; // whether 0 or 1
virtual void receive(int otherChoice); // virtual means it can be overridden in subclases
};

receive 方法将在 Fickle 和其他从 Player 类派生的类中被覆盖

更新 2:

好的,我认为错误实际上是由于代码的不同部分造成的。

播放器定义了一个方法receive:

virtual void receive(int otherChoice);

这应该被 Fickle 的子类覆盖,但 Fickle 中的定义:

void Fickle::receive(int otherChoice) {}

给出错误:

no 'void Fickle::receive(int)' member function declared in class 'Fickle'

但我不知道为什么这是因为在 Player 类中定义了接收?

【问题讨论】:

  • 你得到什么错误? Fickle 的定义是什么(基类的第一行)?
  • 有什么理由不使用std::vector? std::vector<Player*> 很简单。更好的(因为您需要管理这些指针)是boost::ptr_vector<Player> 或std::vector<shared_ptr<Player>>。
  • “不起作用”是什么意思?就指针类型而言,它确实有效,因此代码中的其他地方一定有一些错误。 Fickle 是否有所需的构造函数?是0 <= i < numPlayersIn?
  • Fickle 是否源自 single 玩家基础(即没有多重继承)?
  • @ybungalobill:无关紧要。即使有多重继承,这个想法也应该有效。

标签: c++ arrays pointers polymorphism derived-class


【解决方案1】:

虽然您可能应该改用向量,但动态分配的数组不能工作并没有真正的原因。这是一些工作演示代码:

#include <iostream>

class Player {
public:
    virtual void show() { std::cout << "Player\n"; }
};

class Fickle : public Player {
public:
    virtual void show() { std::cout << "Fickle\n"; }
};

int main() {
    Player **p = new Player *[2];
    p[0] = new Player;
    p[1] = new Fickle;

    for (int i=0; i<2; i++)
        p[i]->show();

    for (int i=0; i<2; i++)
        delete p[i];
    delete [] p;
    return 0;
}

【讨论】:

  • 为什么 Player 在这里被声明为结构体?如果 Player 是一个类而不是一个结构,它会有所不同吗?
  • @tree-hacker:它只是节省了输入public:。这是它唯一真正的区别。为了避免混淆,我用public: 做了两个类。
【解决方案2】:

Fickle 是否有接受int 或指针类型的构造函数?是从Player私下派生的吗?否则它看起来应该可以工作。

【讨论】:

  • 是的,Fickle 确实有一个 int 构造函数。我认为它是从 Player 公开派生的(请参阅有问题的代码),但对派生类不太确定。
【解决方案3】:

看起来你在 Fickle 类的末尾忘记了一个分号:

class Fickle: public Player {
    // ...
}; // <---- this semicolon

也许在别的地方。

更新 2:当你在派生类中重写一个虚函数时,你也必须在那里声明它。

【讨论】:

  • 对于这样一个常见的错误,很难追查到。
  • @Mark Ransom:怪 C++ 预处理器。当它来自某些包含的末尾时尤其困难。当我还是一个新手时,我浪费了一个小时来跟踪这个错误。
  • 好吧,我不知道你还必须在派生类中声明被覆盖的函数。
【解决方案4】:

如果编译不正确,那么您可能没有在您拥有该代码的同一源文件中 #include 定义 Fickle 的标头。通常这样的错误意味着编译器不知道Fickle 是什么。

【讨论】:

    猜你喜欢
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2020-06-15
    • 2016-05-31
    • 2021-12-15
    • 2020-07-26
    • 1970-01-01
    相关资源
    最近更新 更多