即使通过引用传递,也将调用基类方法而不是派生方法 [英] Base class method being called instead of derived, even when passed by reference
问题描述
我有3个类别:A
,B
和AnotherClass
.其中B
是从A
派生的:
class A {
public:
A(){}
virtual void method() {//default action}
};
然后我有一个派生类B:
class B : public A {
public:
B(){}
void method() {//redefine action}
};
和AnotherClass
:
class AnotherClass {
public:
AnotherClass(A& a);
A a;
anotherMethod(){ a.method()}
};
AnotherClass :: AnotherClass(A& a) : a(a) //initialization
因此,如果我用B
的对象构造了AnotherClass
的对象:
B b();
AnotherClass myObj(b);
请记住,由于B
是从A
继承的,并且AnotherClass
接受A
的对象,因此我能够成功地将B
对象作为参数传递.
然后我打电话给
myObj.anotherMethod();
我希望它执行anotherMethod()
,并且当它执行时,我希望它调用属于B
的REDEFINED method()
,但是它将调用A
中定义的默认method()
>
我当时在想我的问题是因为我将AnotherClass
的参数指定为class A
的对象.但是,我不想将此参数更改为class B
的对象,因为我也有类C
,D
和E
,它们也直接从A
继承.因此,我想使用基类作为参数类型,因此我不仅限于只能传递b
对象.但是,我在该站点上阅读了一些较旧的文章,大多数建议的解决方案是通过引用传递派生对象(b
).
有人可以解释为什么会这样吗?
构造函数的参数很好.它是类型为B
的对象,该对象通过引用传递给A
子对象.问题是您将A
子对象仅(而不是派生对象)复制到成员变量a
中.然后,当您调用a.method()
时,那里只有一个基础对象,因此将调用基础函数.
解决方案是使成员变量成为参数的指针或引用(而不是副本). (请注意,无论哪种情况,您都需要确保传入的对象的生存时间至少与AnotherClass
对象一样长.
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?
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.
这篇关于即使通过引用传递,也将调用基类方法而不是派生方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!