2

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

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

4 回答 4

2

You need to store pointers to A so that your new B object won't get "sliced" (see explanation here) when pushed into the vector.

Also, when you want to use specifically a child method / variable on a pointer from the base class, you need to cast it into the proper type

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

Casting an object like this can be dangerous if you are not 100% sure that it is of the type you're casting it in.

See this thread for more information on casting (C style, dynamic_cast and static_cast)

于 2012-11-26T17:14:50.177 回答
1

由于vector被声明为保存类型的对象A,因此当您将 a 推入B向量时,所有B-ness 都会从存储在vector. 这被称为切片问题

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

为了解决这个问题,你需要A不按值存储对象,而是按引用或指针存储对象。您不能将引用存储在 a 中vector,因此这会给您留下指针。

于 2012-11-26T17:19:22.230 回答
0

This has nothing to with vectors. If B derives from A then the following code:

A a;
B b = a;

is an error (unless there is some method to convert).

This is correct - your vector items you should be able to handle uniformly. If this means the code that uses the vector expects all items to be B then just make a vector<B>. If not, then you have no business converting an A to a B anyway.

于 2012-11-26T17:14:19.870 回答
0

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

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

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

于 2012-11-26T17:24:15.687 回答