C++访问抽象类指针向量的子类的成员

C++ accessing member of subclass of abstract class pointer vector

本文关键字:子类 成员 向量 指针 访问 抽象类 C++      更新时间:2023-10-16

此处的错误:

Rocket.cpp:31:16: error: no member named 'getThrust' in 'RocketPart'
    rocket[0]->getThrust();

当我想用rocket[i]->getThrust()通过vector<RocketPart*> rocket从类Engine访问getThrust()时,我会从问题的顶部收到错误消息。我做错了什么?是否可以通过rocket[index]->getThrust((访问它?

RocketPart中没有函数getThrust(),这就是调用函数的向量不起作用的原因。如果getThrust()是一个通用例程,将在从它继承的类中使用,那么您应该将它作为一个虚拟函数添加到基类中,如下所示:

class RocketPart {
public:
    RocketPart();
    RocketPart(const RocketPart& orig);
    virtual ~RocketPart();
    virtual float getThrust();
    virtual void print() = 0;
protected:
    // some members
};

您收到的错误是正确的:类RocketPart中没有名为getThrust的函数。您可以:

  • RocketPart类中添加一个virtual float getThrust()。这可能不是一个好的解决方案,因为并非所有的RocketPart都能包含推力;但是,您可以简单地从中创建return 0,或者使其成为一个纯虚拟函数(这意味着您将不再创建RocketPart对象
  • dynamic_cast将您的RocketPart对象转换为Engine。这可以通过以下方式完成:

    for (size_t r = 0; r < rocket.size(); ++r) { if (const Engine* engine = dynamic_cast<Engine*>(rocket[r])) { // able to successfully convert this RocketPart into an Engine engine.getThrust(); } }

您将无法投射任何不是EngineRocketPart*

这是因为容器中存储的类型是RocketPart。您需要向下转换指向引擎的指针。所以不是
rocket[0]->getThrust();

你需要写:

Engine *pPart = (Engine *) rocket[i]; //you can use also static_cast<> or dynamic_cast<>
pPart->getThrust();

使用cast时要小心:如果rocket[i]不是Engine,程序很可能会崩溃。

您需要添加

virtual float getThrust() = 0;

在您的RocketPart课程中。此外,我认为绝对没有理由使用虚拟继承(只有当您从多个类继承并且存在钻石问题时才需要使用虚拟继承(,因此:

class Engine : virtual public RocketPart {

你应该可以接受:

class Engine : public RocketPart {

如果您的示例源代码不仅仅是一个示例(您正在泄漏Engine对象,也许vector<shared_ptr<Engine>>会是一个更好的主意?(

,我还建议查看您的内存分配方法getThrust((是在Engine类中定义的,而不是在RocketPart中。您需要移动基类RocketPart中的方法,以便通过向量访问它。或者,您也可以使用动态转换将RocketPart"转换"为Engine。
Engine* engine = dynamic_cast<Engine>(rocket[index]);
if (engine) {
    engine->getThrust();
}

考虑到dynamic_cast的使用通常意味着糟糕的设计。