分享
 
 
 

C++ FAQ Lite[24]--继承(私有和保护继承)(更新)

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

[24] 继承 — 私有继承和保护继承

(Part of C++ FAQ Lite, ]Copyright © 1991-2001, Marshall Cline, cline@parashift.com)

简体中文版翻译:申旻nicrosoft@sunistudio.com东日制作室东日文档

FAQs in section [24]:

][24.1] 如何表示“私有继承”?

][24.2] 私有继承和组合(composition)有什么类似?

][24.3] 我应该选谁:组合还是私有继承?

][24.4] 从私有继承类到父类需要指针类型转换吗?

][24.5] 保护继承和私有继承的关系是什么?

][24.6] 私有继承和保护继承的访问规则是什么?

[24.1] 如何表示“私有继承”?

用 : private 代替 : public,例如

class Foo : private Bar {

public:

// ...

};

[ Top | Bottom | Previous section | Next section ]

[24.2] 私有继承和组合(composition)有什么类似?

[Recently changed the syntax to using Engine::start; and added the sixth distinction thanks to Stan Brown; added the third similarity; added "aggregation" as another synonym; general wordsmithing (on 4/01). ]Click here to go to the next FAQ in the "chain" of recent changes.]

私有继承是组合的一种语法上的变形(聚合或者 “有一个”)

例如,“汽车有一个(has-a)引擎”关系可以用单一组合表示为:

class Engine {

public:

Engine(int numCylinders);

void start(); // Starts this Engine

};

class Car {

public:

Car() : e_(8) { } // Initializes this Car with 8 cylinders

void start() { e_.start(); } // Start this Car by starting its Engine

private:

Engine e_; // Car has-a Engine

};

同样的“有一个”关系也能用私有继承表示:

class Car : private Engine { // Car has-a Engine

public:

Car() : Engine(8) { } // Initializes this Car with 8 cylinders

using Engine::start; // Start this Car by starting its Engine

};

两种形式有很多类似的地方:

两种情况中,都只有一个 Engine 被确切地包含于 Car 中

两种情况中,在外部都不能将 Car* 转换为 Engine*

两种情况中,Car类都有一个start()方法,并且都在包含的Engine对象中调用start()方法。

也有一些区别:

如果你想让每个 Car都包含若干 Engine,那么只能用单一组合的形式

私有继承形式可能引入不必要的多重继承

私有继承形式允许 Car 的成员将 Car* 转换成Engine*

私有继承形式允许访问基类的保护(protected)成员

私有继承形式允许 Car 重写 Engine 的虚函数

私有继承形式赋予Car一个更简洁(20个字符比28个字符)的仅通过 Engine调用的start()方法

注意,私有继承通常用来获得对基类的 protected: 成员的访问,但这只是短期的解决方案(]权宜之计

[ Top | Bottom | Previous section | Next section ]

[24.3] 我应该选谁:组合还是私有继承?

[Recently changed so it uses new-style headers and the std:: syntax (on 7/00). ]Click here to go to the next FAQ in the "chain" of recent changes.]

尽可能用组合,万不得已才用私有继承

通常你不会想访问其他类的内部,而私有继承给你这样的一些的特权(和责任)。但是私有继承并不有害。只是由于它增加了别人更改某些东西时,破坏你的代码的可能性,从而使维护的花费更昂贵。

当你要创建一个 Fred 类,它使用了 Wilma 类的代码,并且Wilma 类的这些代码需要调用你新建的 Fred 类的成员函数。在这种情况下,Fred 调用 Wilma 的非虚函数,而Wilma 调用(通常是]纯虚函数)被Fred重写的这些函数。这种情况,用组合是很难完成的。

class Wilma {

protected:

void fredCallsWilma()

{

std::cout << "Wilma::fredCallsWilma()\n";

wilmaCallsFred();

}

virtual void wilmaCallsFred() = 0; // ]纯虚函数

};

class Fred : private Wilma {

public:

void barney()

{

std::cout << "Fred::barney()\n";

Wilma::fredCallsWilma();

}

protected:

virtual void wilmaCallsFred()

{

std::cout << "Fred::wilmaCallsFred()\n";

}

};

[ Top | Bottom | Previous section | Next section ]

[24.4] 从私有继承类到父类需要指针类型转换吗?

一般来说,不。

对于该私有继承类的成员函数或者友元来说,和基类的关系是已知的,并且这种从PrivatelyDer* 到 Base* (或 PrivatelyDer& 到 Base&)的向上转换是安全的,不需要也不推荐进行类型转换。

然而,对于该私有继承类(PrivatelyDer)的用户来说,应该避免这种不安全的转换。因为它基于PrivatelyDer的私有实现,它可以自行改变。

[ Top | Bottom | Previous section | Next section ]

[24.5] 保护继承和私有继承的关系是什么?

[Recently renamed "subclass" to "derived class" (on 7/00). ]Click here to go to the next FAQ in the "chain" of recent changes.]

相同点:都允许重写私有/保护基类的虚函数,都不表明派生类“是一种(a kind-of)”基类。

不同点:保护继承允许派生类的派生类知道继承关系。如此,子孙类可以有效的得知祖先类的实现细节。这样既有好处(它允许保护继承的子类使用它和保护基类的关联)也有代价(保护派生类不能在无潜在破坏更深派生类的情况下改变这种关联)。

保护继承使用 : protected 语法:

class Car : protected Engine {

public:

// ...

};

[ Top | Bottom | Previous section | Next section ]

[24.6] 私有继承和保护继承的访问规则是什么?

[Recently renamed "subclass" to "derived class" (on 7/00). ]Click here to go to the next FAQ in the "chain" of recent changes.]

以这些类为例:

class B { /*...*/ };

class D_priv : private B { /*...*/ };

class D_prot : protected B { /*...*/ };

class D_publ : public B { /*...*/ };

class UserClass { B b; /*...*/ };

子类都不能访问 B 的私有部分。在 D_priv中,B 的公有和保护部分都是私有的。在 D_prot中,B 的公有和保护部分都是保护的。在 D_publ 中,B 的公有部分是公有的,B 的保护部分是保护的(D_publ 是一种 B)。UserClass 类仅仅可以访问 B 的公有部分。

要使 B 的公有成员在 D_priv 或 D_prot中也是公有的,则使用 B:: 前缀声明成员的名称。例如,要使 B::f(int,float)成员在 D_prot中公有,应该这样写:

class D_prot : protected B {

public:

using B::f; // 注意: 不是 using B::f(int,float)

};

[ Top | Bottom | Previous section | Next section ]

E-mail the author

[ C++ FAQ Lite | Table of contents | Subject index | ]About the author | | ]Download your own copy ]

Revised Apr 8, 2001

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有