为什么这个简单的C ++类层次结构无法表现出多态行为?

时间:2010-11-17 19:56:43

标签: c++ polymorphism

如果有人能够通过以下行为启发我,我会很感激 - 我用一个简短的代码示例捕获了它:

//header.h

class base
{
public:
 base(int data):data1(data){}
 virtual int getData(){return data1;}
private:
 int data1;
};

class derived1 :public base
{
public:
 derived1(int data):base(data-1),data2(data){}
 virtual int getData(){return data2;}
private:
 int data2;
};

class derived2 :public derived1
{
public:
 derived2(int data):derived1(data-1),data3(data){}
 virtual int getData(){return data3;}
private:
 int data3;
};


//main.cpp

derived1 d1(20);
derived2 d2(10);

base& baseRefd1 = d1, baseRefd2 = d2; 

cout << "call to baseRefd1.getData() yields: " << baseRefd1.getData();
cout << "call to baseRefd2.getData() yields: " << baseRefd2.getData();

derived1& derived1Refd1 = d1, derived1Refd2 = d2; 

cout << "call to derived1Refd1.getData() yields: " << derived1Refd1.getData();
cout << "call to derived1Refd2.getData() yields: " << derived1Refd2.getData();

输出:

call to baseRefd1.getData() yields: 20  
call to baseRefd2.getData() yields: 8  

call to derived1Refd1.getData() yields: 20  
call to derived1Refd2.getData() yields: 9  

正如您所看到的,当基本引用用作单个派生级别的句柄时,我们会获得多态性 - 调用的getData()版本是派生类的版本。

但是当相同的基本引用被用作层次结构中派生的2个级别的类的句柄时,没有多态性 - 所调用的getData的版本是基础的版本。

当使用类型为derived1的引用时,即层次结构中间层的引用时,即使句柄指向1级别,也没有多态性。

我确信我需要在这里学习一些基本知识。非常感谢任何指导。

3 个答案:

答案 0 :(得分:13)

base& baseRefd1 = d1, baseRefd2 = d2;  

这与

相同
base& baseRefd1 = d1;
base  baseRefd2 = d2;  
    ^ baseRefd2 is not a reference!

你需要另一个&符号:

base& baseRefd1 = d1, & baseRefd2 = d2;  
                      ^ this makes baseRefd2 a reference

这是遵循规则的最佳理由之一“一次只声明一个变量,特别是在声明指针或引用时。”

答案 1 :(得分:3)

实际上可以在不重复&符号的情况下声明多个引用:

template <typename T>
struct reference_to
{
    typedef T & type;
};

reference_to<base>::type baseRefd1 = d1, baseRefd2 = d2;

答案 2 :(得分:1)

baseRefd2和derived1Refd2不是它们是副本的引用。

你的变量声明应该受到指责。你写的是什么,如果分成2行看起来像:

base& baseRefd1 = d1;
base baseRefd2 = d2;

derived1& derived1Refd1 = d1;
derived derived1Refd2 = d2;

(注意每个第二次声明中没有放大器)

在一行上声明这些的正确方法是:

base& baseRefd1 = d1, &baseRefd2 = d2;   

derived1& derived1Refd1 = d1, &derived1Refd2 = d2; 

(注意新的&符号)