Effective C++ 2e Item44

原创 2001年08月05日 19:04:00

条款44: 说你想说的;理解你所说的

在本章关于 "继承和面向对象设计" 的简介中,我曾强调,理解不同的面向对象构件在C++中的含义十分重要。这和仅仅知道C++语言的规则有很大的不同。例如,C++规则说,如果类D从类B公有继承,从D的指针到B的指针就有一个标准转换;B的公有成员函数将被继承为D的公有成员函数,等等。这些规则都是正确的,但在将设计思想转化为C++的过程中,它们起不到任何作用。相反,你需要知道,公有继承意味着 "是一个",如果D从B公有继承,类型D的每一个对象也 "是一个" 类型B的对象。因而,如果想在设计中表示 "是一个",就自然会想到使用公有继承。

"说出你想说的" 只是成功的一半。事情的另一面是 "理解你所说的",这一点同样重要。例如,将成员函数声明为非虚函数会给子类带来限制,如果没有认识到这一点就随便这样做将是不负责任的行为 ---- 除非你完全是有意这么做。声明一个非虚成员函数,你实际上是在说这个函数表示了一种特殊性上的不变性;如果不明白这一点,将会给程序带来灾难。

公有继承和 "是一个" 的等价性,以及非虚成员函数和 "特殊性上的不变性" 的等价性,是C++构件如何和设计思想相对应的例子。下面的列表总结了这些对应关系中最重要的几个。

· 共同的基类意味着共同的特性。如果类D1和类D2都把类B声明为基类,D1和D2将从B继承共同的数据成员和/或共同的成员函数。见条款43。
· 公有继承意味着 "是一个"。如果类D公有继承于类B,类型D的每一个对象也是一个类型B的对象,但反过来不成立。见条款35。
· 私有继承意味着 "用...来实现"。如果类D私有继承于类B,类型D的对象只不过是用类型B的对象来实现而已;类型B和类型D的对象之间不存在概念上的关系。见条款42。
· 分层意味着 "有一个" 或 "用...来实现"。如果类A包含一个类型B的数据成员,类型A的对象要么具有一个类型为B的部件,要么在实现中使用了类型B的对象。见条款40。

下面的对应关系只适用于公有继承的情况:

· 纯虚函数意味着仅仅继承函数的接口。如果类C声明了一个纯虚函数mf,C的子类必须继承mf的接口,C的具体子类必须为之提供它们自己的实现。见条款36。
· 简单虚函数意味着继承函数的接口加上一个缺省实现。如果类C声明了一个简单(非纯)虚函数mf,C的子类必须继承mf的接口;如果需要的话,还可以继承一个缺省实现。见条款36。
· 非虚函数意味着继承函数的接口加上一个强制实现。如果类C声明了一个非虚函数mf,C的子类必须同时继承mf的接口和实现。实际上,mf定义了C的 "特殊性上的不变性"。见条款36。

Effective C++ 目录

改变旧有的C习惯(Shifting from C to C++) 013 条款1:尽量以 const 和 inline 取代 #define 013 Prefer const and inline...
  • sunrise918
  • sunrise918
  • 2011年08月19日 17:34
  • 492

Effective C++ 2e Item25

条款25: 避免对指针和数字类型重载快速抢答:什么是“零”?更明确地说,下面的代码会发生什么?void f(int x);void f(string *ps);f(0);               ...
  • lostmouse
  • lostmouse
  • 2001年07月15日 18:27
  • 697

Effective C++ 2e Item3

条款3:尽量用new和delete而不用malloc和freemalloc和free(及其变体)会产生问题的原因在于它们太简单:他们不知道构造函数和析构函数。假设用两种方法给一个包含10个string...
  • lostmouse
  • lostmouse
  • 2001年06月29日 19:39
  • 873

Effective C++ 2e Item42

条款42: 明智地使用私有继承条款35说明,C++将公有继承视为 "是一个" 的关系。它是通过这个例子来证实的:假如某个类层次结构中,Student类从Person类公有继承,为了使某个函数成功调用,...
  • lostmouse
  • lostmouse
  • 2001年08月02日 19:18
  • 649

Effective C++ 2e Item17

 条款17: 在operator=中检查给自己赋值的情况做类似下面的事时,就会发生自己给自己赋值的情况:class X { ... };X a;a = a;                     /...
  • lostmouse
  • lostmouse
  • 2001年07月09日 20:14
  • 634

Effective C++ 2e Item35

继承和面向对象设计很多人认为,继承是面向对象程序设计的全部。这个观点是否正确还有待争论,但本书其它章节的条款数量足以证明,在进行高效的C++程序设计时,还有更多的工具听你调遣,而不仅仅是简单地让一个类...
  • lostmouse
  • lostmouse
  • 2001年07月29日 18:38
  • 585

Effective C++ 2e Item26

条款26: 当心潜在的二义性每个人都有思想。有些人相信自由经济学,有些人相信来生。有些人甚至相信COBOL是一种真正的程序设计语言。C++也有一种思想:它认为潜在的二义性不是一种错误。这是潜在二义性的...
  • lostmouse
  • lostmouse
  • 2001年07月15日 18:28
  • 627

Effective C++ 2e Item4

条款4:尽量使用C++风格的注释旧的C注释语法在C++里还可以用,C++新发明的行尾注释语法也有其过人之处。例如下面这种情形:    if ( a > b ) {      // int temp =...
  • lostmouse
  • lostmouse
  • 2001年06月29日 20:41
  • 751

Effective C++ 2e Item31

条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用本条款听起来很复杂,其实不然。它只是一个很简单的道理,真的,相信我。先看第一种情况:返回一个局部对象的引用。它的问题...
  • lostmouse
  • lostmouse
  • 2001年07月23日 20:24
  • 669

Effective C++ 2e Item7

条款7:预先准备好内存不够的情况operator new在无法完成内存分配请求时会抛出异常(以前的做法一般是返回0,一些旧一点的编译器还这么做。你愿意的话也可以把你的编译器设置成这样。关于这个话题我将...
  • lostmouse
  • lostmouse
  • 2001年07月02日 16:25
  • 931
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Effective C++ 2e Item44
举报原因:
原因补充:

(最多只允许输入30个字)