二义性
在面向对象中,常常存在这样的事情,一个派生类它有两个或两个以上的基类,这种行为称作多重继承,示意图如下:
如果在多重继承中ClassA和ClassB存在同名数据成员,则对ClassC而言这个同名的数据成员容易产生二义性问题。这里的二义性是指无法直接通过变量名进行读取,需要通过域(::)成员运算符进行区分。例如:
//基类AclassA{public:A():m_data(1),m_a(1){}~A(){}public:intm_data;//同名变量,类型无要求intm_a;};//基类BclassB{public:B():m_data(1),m_b(1){}~B(){}public:intm_data;//同名变量,类型无要求intm_b;};classC:publicA,publicB{};int_tmain(intargc,_TCHAR*argv[]){CData;//Data.m_data=10;//错误,提示指向不明确//通过域成员运算符才可以访问,使用不方便Data.A::m_data=10.1;Data.B::m_data=20;std::coutData.A::m_data""Data.B::m_datastd::endl;return0;}
分析
我们可以通过域(::)运算符对同名变量进行读写操作,但是不是很方便,不能直接通过.变量的形式进行操作,形如Data.m_data。
菱形继承
在多重继承中,存在一个很特殊的继承方式,即菱形继承。比如一个类C通过继承类A和类B,但是类A和类B又同时继承于公共基类N。示意图如下:
这种继承方式也存在数据的二义性,这里的二义性是由于他们间接都有相同的基类导致的。这种菱形继承除了带来二义性之外,还会浪费内存空间。
代码如下:
//公共基类classN{public:N(intdata1,intdata2,intdata3):m_data1(data1),m_data2(data2),m_data3(data3){std::cout"call