C ++ - 从向量中获取派生类变量

时间:2012-11-26 17:08:00

标签: c++ inheritance vector

我真的很困惑,所以我不得不问这个。我尝试编写一个应用程序,但我不知道如何到达派生类的变量,这些变量位于Base类的向量中。 代码是:

class A {
public:
    A() { };

    std::vector<A> aVector;

    void Foo();
}

class B : public A {
public:
    B() { };

    int j;
}

void A::Foo() {
    aVector.push_back( B() );

    // Here I would like to reach B::j, but only the members and variables of A comes in
    aVector[0].j; // wrong
    B b = aVector[0];   // no suitable user-defined conversion from "A" to "B" exists
                        // should I use cast? which one?
}

我目前正在通过应用程序编程学习继承和这类事情,现在我真的被卡住了。

我寻找其他问题,但找不到任何解决我问题的方法。如果有,我错过了,那么抱歉。

4 个答案:

答案 0 :(得分:2)

您需要将pointers存储到A,以便在推入向量时,新的B对象不会被“切片”(请参阅​​解释here)。

此外,如果要在基类的指针上特别使用子方法/变量,则需要cast将其转换为正确的类型

std::vector<A*> aVector;
aVector.push_back(new B());
B* b = (B*)aVector[0];
cout << b->j;
// remember to delete the content of aVector

如果您不是100%确定它是您正在投射的类型,那么投射这样的对象可能会很危险。

有关投射的更多信息,请参见this threadC styledynamic_caststatic_cast

答案 1 :(得分:1)

由于vector被声明为保存A类型的对象,当您将B推入向量时,所有B - 都被剥离存储在vector中的对象。这称为slicing problem

当您稍后尝试访问B中存储的对象的vector元素时,您无法访问它们,因为它们根本不存在。您没有vector个B对象 - 您有vectorA个对象。

为了解决这个问题,您需要存储A个对象,而不是按值,但通过引用或指针。您无法在vector中存储引用,因此这会为您提供指针。

答案 2 :(得分:0)

这与矢量无关。如果B派生自A,则输入以下代码:

A a;
B b = a;

是一个错误(除非有一些转换方法)。

这是正确的 - 您应该能够统一处理的矢量项目。如果这意味着使用向量的代码需要所有项目为B,那么只需创建一个vector<B>。如果没有,那么您无法将A转换为B

答案 3 :(得分:0)

您永远不应该尝试从基类访问派生类成员。基类应该与派生类的实现细节无关。你在做什么不是多态的。换句话说,您的B实例不能像A实例一样,因为您没有提供任何虚拟方法并且不会覆盖任何虚拟方法。

整个设计和方法都不正确。 A :: Foo()应该是一个虚方法(甚至可能是抽象的)。你应该在B :: Foo()中完成工作。

另外一件事,你不应该只持有一个普通老A的向量。它应该是指向A.所以std :: Vector。该成员应以字母m为前缀,以表明它是该类的成员变量。所以std :: vector mSomething;