class="MsoNormal">成员访问属性:
?
1.??? 1.不可访问
2.??? 2.私有
3.??? 3.保护
4.??? 4.公有
?
一.基类与派生类有同名成员:(二义性问题)
?
一般说来,在派生类中对基类成员的访问应该是唯一的,但是,由于多继承情况下,可能造成对基类中某成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。
?
用“对象名.成员名”“对象指针->成员名”的方式先访问派生类的,如果派生类没有新增与基类的同名成员,此时基类有多个同名成员,则系统无法判断该调用哪个成员.如果访问基类的数据成员则要用到这样的方法:“派生类对象.基类::同名成员”? 或 “派生类对象->基类::同名成员”。
此外在派生类的声明时,还可以用using关键字加以澄清,避免二义性问题。
Class Derived:public Base1,public Base2
{
Public:
using Base1::var;
using Base1::fun();
};
Int main()
{
Derived d;
Derived *p=&d;
d.var=1;
d.fun();
d.Base1::var=1;
d.Base1::fun();
p->Base2::var=3;
p->Base2::fun();
return 0;
}
?
二.虚基类:
将共同的基类设置为虚基类,这时候从不同路径继承过来的同名数据成员就只有一个副本,同一个函数名也只有一个映射。
?C有四个基类B1B2B3为直接基类,B0为最远基类
虚基类在派生类的定义过程中声明,语法形式为:
Class 派生类名:virtual 继承方式 基类名
?
?
三.虚基类及派生类的构造函数
<!--[if !supportLists]-->1.??? <!--[endif]-->必须包含所有的数据成员(包括不可见)
<!--[if !supportLists]-->2.??? <!--[endif]-->调用基类构造函数来初始化基类成员,可调用多个基类构造函数。(注意顺序)
在多继承的情况下,派生类的构造函数格式如下:
?
<派生类名>(<总参数表>):<基类名1>(<参数表1>),<基类名2>(<参数表2>),…
<子对象名>(<参数表n+1>),…
{
<派生类构造函数体>
}
其中,<总参数表>中各个参数包含了其后的各个分参数表。
class Base0{
public:
Base0(int var):var0(var){}
Int var0;
Void fun0(){}
};
class Base1:virtual public Base0{
public:
Base1(int var):Base0(var){}//初始化Base0的成员
int var;
};
Class Base2:virtual public Base0{
public:
Base2(int var):Base0(var){} //初始化Base0的成员
int var;
}
class Derived : public Base1,public Base2{
public:
Derived(int var) : Base0(var),Base1(var),Base2(var){} //初始化Base0的成员
Int var;
Void fun(){}
}
Int main()
{
Derived d(1);
d.var=9;
d.fun();
return 0;
}
建立d对象的时候,通过其构造函数初始化列表,因为Derived为最远派生类,虚基类烦人成员则有最远派生类的构造函数调用虚基类的构造函数进行初始化,改派生类的其他基类(Base1,Base2)对虚基类的构造函数调用被自动忽略。