Base class method being called instead of derived, even when passed by reference [duplicate]

陌路散爱 提交于 2019-12-13 14:27:51

问题


I have 3 classes: A, B, and AnotherClass. Where B is derived from A:

class A {
public:
    A(){}
    virtual void method() {//default action}
};

Then I have a derived class, B:

class B : public A {
public:
    B(){}
    void method() {//redefine action}
};

And AnotherClass:

class AnotherClass {
public:
    AnotherClass(A& a);
    A a;
    anotherMethod(){ a.method()}
};
AnotherClass :: AnotherClass(A& a) : a(a) //initialization

So, if I construct an object of AnotherClass with an object of B:

B b();
AnotherClass myObj(b);

Keep in mind, since B inherits from A, and AnotherClass accepts an object of A, I am able to successfully pass in a B object as the argument.

And I call:

myObj.anotherMethod();

I expect this to execute anotherMethod(), and when it does, I expect it to call the REDEFINED method() that belongs to B, but instead it calls the default method() defined in A

I was thinking my problem is because I specify the argument of AnotherClass as an object of class A. However, I do not want to change this argument to an object of class B because I also have classes C, D, and E, that also inherit directly from A. So I want to use the base class as the argument type so I am not limited to only being able to pass in a b object. But, I read some older posts on this site and most proposed solutions was to pass the derived object (b) by reference, which I am doing.

Can someone explain why this is happening?


回答1:


The argument to the constructor is fine. It is an object of type B passed by reference to the A subobject. The problem is that you copy the A subobject only (and not the derived object) into the member variable a. Then when you call a.method() there is only a base object there, so the base function is called.

The solution is to make the member variable be a pointer or a reference (and not a copy) of the argument. (Note that in either case, you will then need to make sure that the object you pass in, will live at least as long as the AnotherClass object.




回答2:


You are slicing in your constructor to AnotherClass. Note you have a value of type A as a member. So the compiler is doing the right thing. You don't have a B at the point you call a.method().




回答3:


It will only work if it is a pointer A* a Look up on polymorphism. http://www.cplusplus.com/doc/tutorial/polymorphism/

if you wont to know more , read the article



来源:https://stackoverflow.com/questions/37732840/base-class-method-being-called-instead-of-derived-even-when-passed-by-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!