问题聚焦:
这一节不涉及代码,但是我们需要明确的一点是,思想比代码要重要得多。
设计优秀的classes是一项艰巨的工作,就像设计好的types一样。
我们应该带着和“语言设计者当初设计语言内置类型时”一样的谨慎来研讨class的设计。
那么,如何设计高效的classes呢?
下面几乎每一个针对class设计的提问,往往就是你所需要遵守的设计规范。
1 新type的对象应该如何被创建和销毁?
这会影响到你的class的构造函数和析构函数以及内存分配函数和释放函数的设计。
2 对象的初始化和对象的赋值该有什么样的差别?
这个答案决定你的构造函数和赋值操作符的行为,以及其间的差异。
很重要的一点:别混淆了“初始化”和“赋值”,因为它们对应于不同的函数调用。
3 新type的对象如果被passed by value,意味着什么?
记住,拷贝构造函数用来定义一个type的pass-by-value该如何实现。
4 什么是新type的合法值?
对class的成员变量而言,通常只有某些值集是有效的。
那些值集决定了你的class:
- 必须维护的约束条件
- 决定了你的成员函数必须进行的错误检查工作
- 影响函数抛出的异常
- 函数异常明细列表
如果你继承自某些既有的classes,你就受那些classes的设计的束缚,特别是受到它们的函数是virtual或non-virtual的影响。
如果你允许其他classes继承你的class,那会影响你所声明的函数,尤其是析构函数。
6 你的新type需要什么样的转换?
你的type生存于其他一堆types之间,因此彼此该有转换行为吗?
如果你希望允许类型T1被隐式转换为类型T2,就必须在class T1内写一个类型转换函数或在class T2内写一个non-explicit-one-arument的构造函数。
7 什么样的操作符和函数对此新type而言是合理的?
这个问题的答案决定你将为你的class声明哪些函数。其中某些该是member函数,某些则不是。
8 什么样的标准函数应该被驳回?
那些正是你必须声明为private的函数。
9 谁该取用新type的成员?
这个提问可以帮你你决定哪个成员为public,哪个为protected,哪个为private。
它也帮助你决定哪一个classes和/或functions应该是friends,以及将它们嵌套于另一个之内是否合理。
10 什么是新type的“未声明接口”?
它对效率,异常安全性以及资源运用提供何种保证?
你在这些方面提供的保证将成为你的class实现代码加上相应的约束条件。
11 你的新type有多么一般化?
或许你其实并非定义一个新type,而是定义个整个types家族。果真如此,你就不应该定义一个新class,而是应该定义一个新的class template。
12 你真的需要一个新type吗?
如果只是定义新的derived class 以便为既有的class 加机能, 那么说不定单纯定义一或多个non-member函数或templates,更能打到目标。
这些问题不容易回答,所以定义出高效的classes是一种挑战。
小结:
class 的设计就是type的设计。
在定义一个新type或class之前,请认真考虑本节的12个问题。
参考资料:
《Effective C++ 3rd》