简介
正如其他 OOP 语言一样,当 C++ 程序员定义了一个新的 class 之后,也相当于定义了一个 type,因此程序员的大部分时间其实是在扩展类型系统。程序员在设计 class 时要像语言设计者设计内置类型一样进行设计,需要考虑重载函数、操作符、内存管理、对象的初始化以及销毁等等。
设计类时需要考虑的问题
我们在设计一个新的类(或者类型)时通常需要考虑以下问题:
新类型的对象应该如何被创建以及销毁?
这个问题主要是影响我们如何编写类的构造函数和析构函数。
对象的初始化和对象的赋值该有什么样的差别?
我们应该明确区分对象的赋值和初始化,并且考虑他们的行为有何不同,以此来决定构造函数和赋值操作符的实现方法。
新类型的对象如果被 passed by value (值传递),意味着什么?
对于这个问题主要思考的是拷贝构造函数的行为。
什么是新类型的合法值?
我们应该思考哪些值才是新类型各成员变量的合法值。对于非合法值,我们应该在成员函数中(尤指构造函数,赋值操作符以及 setter 函数)进行检查。
新类需要配合某个继承图系吗?
如果新类型是继承于某一个类下,会受该类的约束(尤其是有虚函数的情况)。而如果新类型需要允许其他类进行继承,那么需要考虑成员函数(尤其是析构函数)需不需要声明为 virtual。
新的类型需要什么转换?
在设计类型时,需要考虑新类型是否允许由别的类型转换而来。假设类型 T1
允许被 T2
隐式转换,那么在 T1
中需要编写接收 T2
对象的构造函数或者写一个 non-explicit-one-argument 的构造函数。假如只允许 explicit 的构造函数存在,则需要对某一个需要转换的类型单独写其类型的构造函数。
对于新类型而言,哪些操作符和函数是合理的?
这个问题中主要影响设计者应该声明哪些函数,并且思考哪些函数应该是成员函数,哪些不应该是。
什么样的标准函数应该拒绝?
主要影响我们把哪些默认函数声明为 private
。
哪些用户应该需要新类型的成员?
这个问题会决定我们将哪些成员分别声明为 public
、protected
、private
。
新类型的未声明接口是什么?
见条款 29。这里需要考虑新类型的未声明接口对效率、异常安全以及资源运用提供什么样的保证。
新类型的一般化程度怎么样?
在设计需要考虑需不需要或者应不应该将类声明为类模板(class template)。
这个新类型真的需要吗?
最终我们还需要考虑我们需要获得新功能有没有可能只需要针对已有的类提供一个或多个非成员函数就可以达到目的。换言之,我们真的需要一个新的类吗?
结论
在设计一个新的类型时,首先需要考虑以上的主题。
其他
- 完整可运行代码地址:Effective-Cpp-Reading-Note
- Efftive C++ 阅读笔记:Effective C++