我真的很困惑,所以我不得不问这个。我尝试编写一个应用程序,但我不知道如何到达派生类的变量,这些变量位于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?
}
我目前正在通过应用程序编程学习继承和这类事情,现在我真的被卡住了。
我寻找其他问题,但找不到任何解决我问题的方法。如果有,我错过了,那么抱歉。
答案 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 thread(C style
,dynamic_cast
和static_cast
)
答案 1 :(得分:1)
由于vector
被声明为保存A
类型的对象,当您将B
推入向量时,所有B
- 都被剥离存储在vector
中的对象。这称为slicing problem。
当您稍后尝试访问B
中存储的对象的vector
元素时,您无法访问它们,因为它们根本不存在。您没有vector
个B对象 - 您有vector
个A
个对象。
为了解决这个问题,您需要存储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;