`
BlogDown
  • 浏览: 228244 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

C++编程规范---第10章 类的继承与组合

 
阅读更多

对象(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么类就是房子的设计图纸。所以面向对象设计的重点是类的设计,而不是对象的设计。

对于C++程序而言,设计孤立的类是比较容易的,难的是正确设计基类及其派生类。本章仅仅论述“继承”(Inheritance)和“组合”(Composition)的概念。

注意,当前面向对象技术的应用热点是COMCORBA,这些内容超出了C++教材的范畴,请阅读COMCORBA相关论著。

继承

如果A是基类,BA的派生类,那么B将继承A的数据和函数。例如:

class A

{

public:

voidFunc1(void);

voidFunc2(void);

};

class B : public A

{

public:

voidFunc3(void);

voidFunc4(void);

};

main()

{

Bb;

b.Func1();// BA继承了函数Func1

b.Func2();// BA继承了函数Func2

b.Func3();

b.Func4();

}

这个简单的示例程序说明了一个事实:C++的“继承”特性可以提高程序的可复用性。正因为“继承”太有用、太容易用,才要防止乱用“继承”。我们应当给“继承”立一些使用规则。

l【规则10-1-1如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能和属性。不要觉得“白吃白不吃”,让一个好端端的健壮青年无缘无故地吃人参补身体。

l【规则10-1-2若在逻辑上BA的“一种”(a kind of),则允许B继承A的功能和属性。例如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类Man可以从类Human派生,类Boy可以从类Man派生。

class Human

{

};

class Man : public Human

{

};

class Boy : public Man

{

};

u注意事项

【规则10-1-2看起来很简单,但是实际应用时可能会有意外,继承的概念在程序世界与现实世界并不完全相同。

例如从生物学角度讲,鸵鸟(Ostrich)是鸟(Bird)的一种,按理说类Ostrich应该可以从类Bird派生。但是鸵鸟不能飞,那么Ostrich::Fly是什么东西?

class Bird

{

public:

virtual void Fly(void);

};

class Ostrich : public Bird

{

};

例如从数学角度讲,圆(Circle)是一种特殊的椭圆(Ellipse),按理说类Circle应该可以从类Ellipse派生。但是椭圆有长轴和短轴,如果圆继承了椭圆的长轴和短轴,岂非画蛇添足?

所以更加严格的继承规则应当是:若在逻辑上BA的“一种”,并且A的所有功能和属性对B而言都有意义,则允许B继承A的功能和属性。

10.2组合

l【规则10-2-1若在逻辑上AB的“一部分”(a part of),则不允许BA派生,而是要用A和其它东西组合出B

例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类EyeNoseMouthEar组合而成,不是派生而成。如示例10-2-1所示。

class Eye

{
public:

voidLook(void);

};

class Nose

{
public:

voidSmell(void);

};

class Mouth

{
public:

voidEat(void);

};

class Ear

{
public:

voidListen(void);

};

//正确的设计,虽然代码冗长。

class Head

{

public:

voidLook(void){m_eye.Look();}

voidSmell(void){m_nose.Smell();}

voidEat(void){m_mouth.Eat();}

voidListen(void){m_ear.Listen();}

private:

Eyem_eye;

Nosem_nose;

Mouthm_mouth;

Earm_ear;

};

示例10-2-1HeadEyeNoseMouthEar组合而成

如果允许HeadEyeNoseMouthEar派生而成,那么Head将自动具有LookSmellEatListen这些功能。示例10-2-2十分简短并且运行正确,但是这种设计方法却是不对的。

//功能正确并且代码简洁,但是设计方法不对。

class Head : public Eye, public Nose, public Mouth, public Ear

{

};

示例10-2-2HeadEyeNoseMouthEar派生而成

一只公鸡使劲地追打一只刚下了蛋的母鸡,你知道为什么吗?

因为母鸡下了鸭蛋。

很多程序员经不起“继承”的诱惑而犯下设计错误。“运行正确”的程序不见得是高质量的程序,此处就是一个例证。


对象(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么类就是房子的设计图纸。所以面向对象设计的重点是类的设计,而不是对象的设计。

对于C++程序而言,设计孤立的类是比较容易的,难的是正确设计基类及其派生类。本章仅仅论述“继承”(Inheritance)和“组合”(Composition)的概念。

注意,当前面向对象技术的应用热点是COMCORBA,这些内容超出了C++教材的范畴,请阅读COMCORBA相关论著。

继承

如果A是基类,BA的派生类,那么B将继承A的数据和函数。例如:

class A

{

public:

voidFunc1(void);

voidFunc2(void);

};

class B : public A

{

public:

voidFunc3(void);

voidFunc4(void);

};

main()

{

Bb;

b.Func1();// BA继承了函数Func1

b.Func2();// BA继承了函数Func2

b.Func3();

b.Func4();

}

这个简单的示例程序说明了一个事实:C++的“继承”特性可以提高程序的可复用性。正因为“继承”太有用、太容易用,才要防止乱用“继承”。我们应当给“继承”立一些使用规则。

l【规则10-1-1如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能和属性。不要觉得“白吃白不吃”,让一个好端端的健壮青年无缘无故地吃人参补身体。

l【规则10-1-2若在逻辑上BA的“一种”(a kind of),则允许B继承A的功能和属性。例如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类Man可以从类Human派生,类Boy可以从类Man派生。

class Human

{

};

class Man : public Human

{

};

class Boy : public Man

{

};

u注意事项

【规则10-1-2看起来很简单,但是实际应用时可能会有意外,继承的概念在程序世界与现实世界并不完全相同。

例如从生物学角度讲,鸵鸟(Ostrich)是鸟(Bird)的一种,按理说类Ostrich应该可以从类Bird派生。但是鸵鸟不能飞,那么Ostrich::Fly是什么东西?

class Bird

{

public:

virtual void Fly(void);

};

class Ostrich : public Bird

{

};

例如从数学角度讲,圆(Circle)是一种特殊的椭圆(Ellipse),按理说类Circle应该可以从类Ellipse派生。但是椭圆有长轴和短轴,如果圆继承了椭圆的长轴和短轴,岂非画蛇添足?

所以更加严格的继承规则应当是:若在逻辑上BA的“一种”,并且A的所有功能和属性对B而言都有意义,则允许B继承A的功能和属性。

10.2组合

l【规则10-2-1若在逻辑上AB的“一部分”(a part of),则不允许BA派生,而是要用A和其它东西组合出B

例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类EyeNoseMouthEar组合而成,不是派生而成。如示例10-2-1所示。

class Eye

{
public:

voidLook(void);

};

class Nose

{
public:

voidSmell(void);

};

class Mouth

{
public:

voidEat(void);

};

class Ear

{
public:

voidListen(void);

};

//正确的设计,虽然代码冗长。

class Head

{

public:

voidLook(void){m_eye.Look();}

voidSmell(void){m_nose.Smell();}

voidEat(void){m_mouth.Eat();}

voidListen(void){m_ear.Listen();}

private:

Eyem_eye;

Nosem_nose;

Mouthm_mouth;

Earm_ear;

};

示例10-2-1HeadEyeNoseMouthEar组合而成

如果允许HeadEyeNoseMouthEar派生而成,那么Head将自动具有LookSmellEatListen这些功能。示例10-2-2十分简短并且运行正确,但是这种设计方法却是不对的。

//功能正确并且代码简洁,但是设计方法不对。

class Head : public Eye, public Nose, public Mouth, public Ear

{

};

示例10-2-2HeadEyeNoseMouthEar派生而成

一只公鸡使劲地追打一只刚下了蛋的母鸡,你知道为什么吗?

因为母鸡下了鸭蛋。

很多程序员经不起“继承”的诱惑而犯下设计错误。“运行正确”的程序不见得是高质量的程序,此处就是一个例证。

分享到:
评论

相关推荐

    C++编程规范101条规则、准则与最佳实践PDF.rar

    第10条 尽量减少全局和共享数据 19 第11条 隐藏信息 20 第12条 懂得何时和如何进行并发性编程 21 第13条 确保资源为对象所拥有。使用显式的RAII和智能指针 24 编程风格 27 第14条 宁要编译时和连接...

    C++编程规范关于C++编程要注意的细节

    #### 第10章 类的继承与组合 **10.1 继承** - 继承是一种使类可以从已有类获取属性和行为的方式。 - 通过继承可以实现代码复用和多态。 **10.2 组合** - 组合是通过将一个对象作为另一个对象的成员来实现的。 - ...

    高质量C++编程指南

    第10章 类的继承与组合 本章解释了继承和组合的概念以及它们在面向对象编程中的应用。 第11章 其他编程经验 本章分享了使用CONST提高函数健壮性的技巧、提高程序效率的建议以及其他有益的编程经验。 参考文献 书末...

    Google C++ 编程规范指南简介

    【Google C++编程规范指南简介】是一份针对C++编程的规范文档,旨在提升代码质量、可读性和可维护性,特别关注了C++语言的高效特性与复杂性之间的平衡。以下是规范中的关键知识点: 1. **代码风格**:代码风格关乎...

    Google C++编码规范.pdf

    该文档为Google公司内部使用的C++编程规范指南,旨在提高代码的一致性与可维护性,同时也适用于其他使用C++进行软件开发的团队和个人。 #### 三、头文件规范 - **#define保护**: 使用`#ifndef`、`#define`及`#endif...

    高质量C++_C编程指南

    《高质量C++/C编程指南》是由林锐博士撰写,旨在为读者提供高质量的软件开发方法和C++/C编程规范。本书不仅包含了软件质量和面向对象程序设计方法的深入讨论,还涉及了C++/C编程风格以及一些技术专题。 书中将软件...

    Visual C++程序设计案例教程-张荣梅-源代码-第一章

    《Visual C++程序设计案例教程》是学习C++编程的重要参考资料,由张荣梅老师编著,本部分主要涵盖的是第一章的源代码。在第一章中,通常会介绍C++的基础知识,包括C++语言的历史、环境搭建、第一个“Hello, World!”...

    C++编程规范 C++初学者必看

    以下是一些关键的C++编程规范知识点: 1. **命名规则**:采用有意义的标识符,如变量、函数、类名等,应清晰反映它们的用途。遵循驼峰命名法(CamelCase)或下划线命名法(snake_case),保持一致性。 2. **注释**...

    编程艺术-c++

    《编程艺术-C++》这本书深入探讨了C++编程语言的艺术与科学,旨在帮助读者掌握C++的核心概念和最佳实践。本书包含丰富的代码示例和详细解释,为初学者和有经验的开发者提供了全面的指导。 C++是一种多范式、静态...

    高质量C/C++编程指南

    #### 第10章 类的继承与组合 - **继承**:利用继承机制来实现代码复用,但要注意避免过度使用。 - **组合**:通过组合对象来构建复杂的类结构,从而提高代码的可维护性和扩展性。 #### 第11章 其它编程经验 - **...

    高效C/C++编程

    #### 第10章 类的继承与组合 - **继承**:阐述了继承的概念及其在类设计中的应用。 - **组合**:介绍了组合的概念及其与继承的比较。 #### 第11章 其他编程经验 - **使用CONST提高函数的健壮性**:解释了如何通过...

    Google C++编程规范.pdf

    ### Google C++编程规范知识点概览 #### 一、头文件 在Google C++编程规范中,关于头文件的部分强调了几个重要的方面: 1. **`#define` 的保护**:为了避免同一个头文件被多次包含导致的问题(如重复定义等),...

    C++编码规范.

    ### C++编码规范 #### 第1章 命名原则 **原则1.1 关于类型名** - 类型名称应当清晰明确,避免使用容易混淆的名称。 - 示例:`int` 类型不应命名为 `Int` 或 `i`。 **原则1.2 关于变量和函数名** - 变量和函数名应...

    高质量C++编程(完整).doc

    第10章讲述了类的继承与组合,这是面向对象编程的核心概念,通过继承和组合可以构建复杂的类层次结构。 第11章提供了一些其他的编程经验,如使用CONST提高函数健壮性、提升程序效率的技巧,以及一些有益的建议,...

    C++编程规范

    ### C++编程规范知识点 #### 一、C++编程规范概览 本文档详细阐述了北京中创信测科技股份有限公司内部对于C++编程的具体规范,旨在通过统一编码风格和实践来提升代码的质量与可维护性。 #### 二、适用范围 此...

    高质量C++编程指南 林锐

    #### 第10章 类的继承与组合 - **继承**:类继承的基础概念及其优缺点。 - **组合**:使用组合而非继承的原则和方法。 #### 第11章 其它编程经验 - **使用const提高函数的健壮性**:const关键字的使用技巧。 - **...

Global site tag (gtag.js) - Google Analytics