Effective C++之条款19:设计class犹如设计type

声明:

  1. 文中内容收集整理自《Effective C++(中文版)第三版》,版权归原书所有。
  2. 本内容在作者现有能力的基础上有所删减,另加入部分作者自己的理解,有纰漏之处敬请指正。

条款19:设计class犹如设计type

Treat class design as type design.

class侧重于自定义的类,而type侧重于系统预定义的类。当你定义了一个新class,也就定义了一个新type。因此应该带着和“语言设计者当初设计语言内置类型时“一样的谨慎来研讨class的设计。

那么如何设计高效的classes呢?

1. 新type的对象该如何被创建和销毁?

这涉及到构造函数和析构函数以及内存分配函数和释放函数new、new[]、delete和delete[]。

2. 对象初始化与对象的赋值应该有什么样的差别?

这涉及到构造函数和赋值操作符的行为,另外注意“初始化”和“赋值”的区别,它们对应于不同的函数调用。

3. 新type的对象如果被pass-by-value意味着什么?

这涉及到拷贝构造函数。

4. 什么是新type的合法值?

对象的成员变量通常只有某些数值集是有效的。

5. 你的新type需要配合某个继承图系吗?

要判断自己设计的class是否需要继承或被继承。如果你允许其他classes继承自你的class,那会影响你生命的函数——尤其是析构函数是否为virtual。

6. 你的新type需要什么样的转换?

主要涉及到隐式转换,如果你希望允许类型T1之物被隐式转换为类型T2,就必须在class T1内写一个类型转换函数(operator T2)或在class T2内写一个non-explicit-one-argument(可被单一实参调用)的构造函数。

类型转换函数的一般形式为:
operator T2()
{
    //实现转换的语句
}

//考虑这个用于字体的RAII
FontHandle getFont(); //C API
void releaseFont(FontHandle fh); //C API
class Font
{
public:
	explicit Font(FontHandle fh) f(fh)
	{ }
	~Font()
	{
		releaseFont(f); //释放资源
	}
	//隐式转换函数,将Font转换为FontHandle
	operator FontHandle() const
	{
		return f;
	}
private:
	FontHandle f; //原始(raw)字体资源
}

转换函数有以下性质: 

  1. 转换函数必须是类的成员函数
  2. 转换函数不能声明返回类型
  3. 形参列表必须为空
  4. 类型转换函数通常应该是const

7. 什么样的操作符和函数对此新type而言是合理的?

8. 什么样的标准函数应该驳回?

即哪些成员声明为private。

9. 谁该取用新type成员?

即类的封装问题,一些而言,成员变量都应该是private的,而在public函数里面提供对这些成员变量的访问get和set函数。如果需要的话,可以使用友元,但友元也要慎用。

10. 什么是新type的未声明接口?

11. 你的新type有多么一般化?

这涉及到泛型编程。

12. 你真的需要一个新type吗?

请记住:

class的设计就是type的设计。在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有主题。

猜你喜欢

转载自blog.csdn.net/longmenshenhua/article/details/88796419