在基类指针向量中,如何访问派生的类成员返回错误

How come accessing derived class member in base class pointer vector returns an error?

本文关键字:派生 访问 错误 返回 成员 向量 指针 基类 何访问      更新时间:2023-10-16

问题的简化示例:

#include <string>
#include <deque>
#include <iostream>
class Action{
    public:
    std::string name;
    Action(std::string name){
        this->name = name;
    }
};
class Ability : public Action{
public:
    int bar;
    Ability(std::string name) : Action(name){}
};
int main(){
    std::deque<Action*> foo;
    Ability test("asdf");
    test.bar = 122;
    foo.push_back(&test);
    std::cout << foo.at(0)->bar << std::endl;
    return 0;
}

这会产生一个错误,即"动作"没有" bar"成员。

我意识到这与对象切片有关,并且我试图使用指针,这使矢量可以推回"能力"对象,但我无法访问其" bar"成员。

我缺少什么?

首先,我们的赞助商的单词:什么是对象切片?

既然您已经阅读了上述链接,则可以看到由于对象未复制到foo中,因此没有切片,只复制了对象的指针。Ability仍然完好无损,无论在内存中坐着 test中的任何地方。

但是... foo包含Action的指针,而不是AbilityFoo的用户无法知道Foo的任何给定元素是否是对ActionAbility或其他Action的其他子类的引用,他们绝对不知道。非常有力的东西,能够与您甚至不知道的事物一起工作的能力,但这是有代价的:您必须像知道的东西一样使用它。Foo的用户只能使用Action的界面。在此方面有很多方法,例如Dynamic_cast,但是在大多数情况下,最好坚持使用所提供的接口,并允许超载的方法或操作员在场景后面做黑魔法,以对Action代表的任何方法做正确的事情。如果这意味着您必须

class Action{
    public:
    std::string name;
    Action(std::string name){
        this->name = name;
    }
    virtual int getbar() = 0; // pure virtual method that all subclasses  
                              // of Action must implement
};
class Ability : public Action{
public:
    int bar;
    Ability(std::string name) : Action(name){}
    int getbar()
    {
        return bar;
    }
};

及以后

std::cout << foo.at(0)->getbar() << std::endl;

这样。