即使通过引用传递,也将调用基类方法而不是派生方法 [英] Base class method being called instead of derived, even when passed by reference

查看:96
本文介绍了即使通过引用传递,也将调用基类方法而不是派生方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个类别:ABAnotherClass.其中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的对象,因为我也有类CDE,它们也直接从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆