2016-06-09 27 views
1

我有3个类:ABAnotherClass。凡BA得出:基类方法被调用而不是派生,即使通过引用传递

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 

所以,如果我构建与AnotherClass对象B的一个对象:

B b(); 
AnotherClass myObj(b); 

请记住,由于B继承自A,并且AnotherClass接受A的对象,因此我能够成功传入B对象作为参数。

我呼吁:

myObj.anotherMethod(); 

我希望这个执行anotherMethod(),当它发生了,我希望它来调用属于B重新定义method(),而是它调用A定义的默认method()

我在想我的问题是因为我指定了AnotherClass作为class A的一个对象的参数。但是,我不想将此参数更改为class B的对象,因为我也有类C,DE,它们也直接从A继承。所以我想使用基类作为参数类型,所以我不仅仅限于能够传递一个b对象。但是,我在本网站上阅读了一些较旧的帖子,大多数提议的解决方案是通过引用传递派生对象(b),我正在这样做。

有人可以解释为什么会发生这种情况吗?

+0

*我想我的问题是因为我指定AnotherClass的参数为A类的一个对象*你是对的,你需要在类中存储一个引用或者指向'A'的指针 – NathanOliver

+0

我编辑过它,但不是这样:'B b();' - 你的代码甚至编译? – Ajay

回答

3

构造函数的参数很好。它是B类型的对象,通过引用A子对象传递。问题在于,您只将A子对象(而不是派生对象)复制到成员变量a中。然后,当您拨打a.method()时,那里只有一个基础对象,因此调用基础函数。

解决方法是使成员变量成为参数的指针或引用(而不是副本)。(请注意,无论哪种情况,您都需要确保传入的对象至少与AnotherClass对象一样长。

0

只有当它是一个指针才能工作A* a 查看多态性。 http://www.cplusplus.com/doc/tutorial/polymorphism/

如果你不会知道更多,请阅读文章

+0

'A * a(b);'是一个汇编错误,'A &a(b);'也可以工作 –

+0

错误并且完全不相关的问题(当他在AnotherClass构造函数中存储对A实例的引用时切片) – kfsone

+0

A * a =新的A(b);这是更好的:)对不起 – kemis

2

您切片在构造函数AnotherClass。请注意,您有一个类型为A的值作为成员。所以编译器正在做正确的事情。您拨打a.method()时没有B

相关问题