分享
 
 
 

多继承

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

多继承可以看作是单继承的扩展。所谓多继承是指派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承。

多继承下派生类的定义格式如下:

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…

{

<派生类类体>

};

其中,<继承方式1>,<继承方式2>,…是三种继承方式:public、private、protected之一。例如:

class A

{

};

class B

{

};

class C : public A, public, B

{

};

其中,派生类C具有两个基类(类A和类B),因此,类C是多继承的。按照继承的规定,派生类C的成员包含了基类B中成员以及该类本身的成员。

多继承的构造函数

在多继承的情况下,派生类的构造函数格式如下:

<派生类名>(<总参数表>):<基类名1>(<参数表1>),<基类名2>(<参数表2>),…

<子对象名>(<参数表n+1>),…

{

<派生类构造函数体>

}

其中,<总参数表>中各个参数包含了其后的各个分参数表。

多继承下派生类的构造函数与单继承下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用。同时,派生类的参数个数必须包含完成所有基类初始化所需的参数个数。

派生类构造函数执行顺序是先执行所胡基类的构造函数,再执行派生类本身构造函数,处于同一层次的各基类构造函数的执行顺序取决于定义派生类时所指定的各基类顺序,与派生类构造函数中所定义的成员初始化列表的各项顺序无关。也就是说,执行基类构造函数的顺序取决于定义派生类时基类的顺序。可见,派生类构造函数的成员初始化列表中各项顺序可以任意地排列。

下面通过一个例子来说明派生类构造函数的构成及其执行顺序。

#include <iostream.h>

class B1

{

public:

B1(int i)

{

b1 = i;

cout<<"构造函数 B1."<<i<<endl;

}

void print() { cout<<b1<<endl; }

private:

int b1;

};

class B2

{

public:

B2(int i)

{

b2 = i;

cout<<"构造函数 B2."<<i<<endl;

}

void print() { cout<<b2<<endl; }

private:

int b2;

};

class B3

{

public:

B3(int i)

{

b3 = i;

cout<<"构造函数 B3."<<i<<endl;

}

int getb3() { return b3; }

private:

int b3;

};

class A : public B2, public B1

{

public:

A(int i, int j, int k, int l):B1(i), B2(j), bb(k)

{

a = l;

cout<<"构造函数 A."<<l<<endl;

}

void print()

{

B1::print();

B2::print();

cout<<a<<","<<bb.getb3()<<endl;

}

private:

int a;

B3 bb;

};

void main()

{

A aa(1, 2, 3, 4);

aa.print();

}

该程序的输出结果为:

构造函数 B2.2

构造函数 B1.1

构造函数 B3.3

构造函数 A.4

1

2

4, 3

在该程序中,作用域运算符::用于解决作用域冲突的问题。在派生类A中的print()函数的定义中,使用了B1::print;和B2::print();语句分别指明调用哪一个类中的print()函数,这种用法应该学会。

二义性问题

一般说来,在派生类中对基类成员的访问应该是唯一的,但是,由于多继承情况下,可能造成对基类中某成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。

实际上,在上例已经出现过这一问题,回忆一下上例中,派生类A的两基类B1和B2中都有一个成员函数print()。如果在派生类中访问print()函数,到底是哪一个基类的呢?于是出现了二义性。但是在上例中解决了这个问题,其办法是通过作用域运算符::进行了限定。如果不加以限定,则会出现二义性问题。

下面再举一个简单的例子,对二义性问题进行深入讨论。例如:

class A

{

public:

void f();

};

class B

{

public:

void f();

void g();

};

class C : public A, public B

{

public:

void g();

void h();

};

如果定义一个类C的对象c1:

C c1;

则对函数f()的访问

c1.f();

便具有二义性:是访问类A中的f(),还是访问类B中的f()呢?

解决的方法可用前面用过的成员名限定法来消除二义性,例如:

c1.A::f();

或者

c1.B::f();

但是,最好的解决办法是在类C中定义一个同名成员f(),类C中的f()再根据需要来决定调用A::f(),还是B::f(),还是两者皆有,这样,c1.f()将调用C::f()。

同样地,类C中成员函数调用f()也会出现二义性问题。例如:

viod C::h()

{

f();

}

这里有二义性问题,该函数应修改为:

void C::h()

{

A::f();

}

或者

void C::h()

{

B::f();

}

或者

void C::f()

{

A::f();

B::f();

}

另外,在前例中,类B中有一个成员函数g(),类C中也有一个成员函数g()。这时,

c1.g();

不存在二义性,它是指C::g(),而不是指B::g()。因为这两个g()函数,一个出现在基类B,一个出现在派生类C,规定派生类的成员将支配基类中的同名成员。因此,上例中类C中的g()支配类B中的g(),不存在二义性,可选择支配者的那个名字。

当一个派生类从多个基类派生类,而这些基类又有一个共同的基类,则对该基类中说明的成员进行访问时,也可能会出现二义性。例如:

class A

{

public:

int a;

};

class B1 : public A

{

private:

int b1;

};

class B2 : public A

{

private:

int b2;

};

class C : public B1, public B2

{

public:

int f();

private:

int c;

};

已知:C c1;

下面的两个访问都有二义性:

c1.a;

c1.A::a;

而下面的两上访问是正确的:

c1.B1::a;

c1.B2::a;

类C的成员函数f()用如下定义可以消除二义性:

int C::f()

{

retrun B1::a + B2::a;

}

由于二义性的原因,一个类不可以从同一个类中直接继承一次以上,例如:

class A : public B, public B

{

}

这是错误的。

2001-8-21 23:00

附带《C++面向对象基础教程》

文件下载: 点击下载 [114KB],[rar格式,下载 Winrar300sc ]

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有