Base class method being called instead of derived, even when passed by reference
我有3个班:A、B和AnotherClass。其中B来源于A:
1 2 3 4 5
| class A {
public:
A(){}
virtual void method() {//default action}
}; |
然后我有一个派生类,B:
1 2 3 4 5
| class B : public A {
public:
B(){}
void method() {//redefine action}
}; |
和AnotherClass:
1 2 3 4 5 6 7
| class AnotherClass {
public:
AnotherClass(A& a);
A a;
anotherMethod(){ a.method()}
};
AnotherClass :: AnotherClass(A& a) : a(a) //initialization |
因此,如果我用B的对象构造AnotherClass的对象:
1 2
| B b();
AnotherClass myObj(b); |
请记住,由于B继承了A,AnotherClass接受了A的对象,所以我可以成功地将B对象作为论据。
我称之为:
我希望它执行anotherMethod(),当它执行时,我希望它调用属于B的重新定义的method(),而不是调用A中定义的默认method()。
我想我的问题是因为我把AnotherClass的论点指定为class A的对象。但是,我不想把这个论点改为class B的一个对象,因为我还有C、D和E类,它们也直接从A继承。所以我想使用基类作为参数类型,这样我不仅能够传递B对象。但是,我在这个网站上看到了一些老的帖子,大多数建议的解决方案是通过引用来传递派生对象(B,我正在这样做。
有人能解释为什么会这样吗?
- 我想我的问题是因为我把另一个类的参数指定为类A的对象,你是正确的。您需要在类中存储指向A的引用或指针。
- 我已经编辑过了,但不是这样的:B b();—您的代码甚至在编译吗?
构造函数的参数可以。它是通过引用A子对象传递的B类型的对象。问题是,只将A子对象(而不是派生对象)复制到成员变量A中。然后,当调用a.method()时,那里只有一个基对象,因此调用基函数。
解决方案是使成员变量成为参数的指针或引用(而不是副本)。(请注意,无论哪种情况,您都需要确保传递的对象至少与AnotherClass对象一样长。
您正在将构造函数切片到AnotherClass。注意,作为成员,您有一个类型为A的值。所以编译器正在做正确的事情。在你称之为a.method()的时候,你没有B。
只有当它是指针A* a时,它才能工作。查找多态性。http://www.cplusplus.com/doc/tutorial/多态性/
如果你不想了解更多,请阅读这篇文章
- A *a(b);是一个编译错误。A &a(b);也将工作。
- 完全错误的和无关的问题(这是切片在他店的参考到一个实例中的anotherclass构造函数)。
- 一个新的A *(b));这是一nicer:对不起。
- 它将无法工作)分为"只读"。b)有显着的工作,你将无法工作。1。
- 构建一个Anew A(b)将复制对象从对象的基础b。打电话的a->method()基类的函数,没有函数衍生类。