Shuffy

不断的学习,不断的思考,才能不断的进步.Let's do better together!
posts - 102, comments - 43, trackbacks - 0, articles - 19
[转]http://www.cppblog.com/tiandejian/archive/2007/05/20/ec_19.html

第18条:     要像设计类型一样设计 class

与其它的面向对象编程语言类似,在 C++ 中,定义一个新的 class 便会引入一个新的类型的定义。一个 C++ 设计人员的大多数时间都会用在不断丰富充实他们的类系统上。这意味着他不仅仅是一个 class 的设计者,而且是一个类型的设计者。重载函数和运算符、控制内存的分配和释放、定义函数用于完成对象初始化和终止操作——这些都由设计人员全权包办。我们知道语言设计人员在设计语言内置的数据类型时倾注了大量心血,而一个类设计人员也要花费差不多的精力。

能否设计出优秀的 class 对于设计人员来说是一项严峻的考验,因为设计类型本身就是一项艰巨的任务。优秀的类型应该拥有自然的语法、直观的语义,并且还要有一套或更多高效的实现。在 C++ 中,如果定义 class 的工作做得一团糟,那么期望达到上面的目标就是天方夜谭。甚至类的成员函数的声明方式也会影响到它的性能。

那么,如何把类设计得更高效呢?首先,你必须要了解你所面对的问题。几乎所有的类都需要你考虑下面的问题,它们的答案可以对设计起到一定的约束作用:

新类型的对象应如何创建和删除? 类中与之相关的函数包括:构造函数和析构函数,以及类中其它的内存分配和释放函数( operator new operator new[] operator delete operator delete[] ,参见第 8 章)。如果你自己手动编写它们,这个问题的解决方式将会影响到这些函数。

对象初始化与对象赋值有什么不同? 这个问题的答案决定着构造函数与赋值运算符之间的区别。不要混淆初始化和赋值的概念,这一点很重要,因为它们与不同的函数调用相关。

对于新类型的对象如何通过传值方式传递? 请牢记,拷贝构造函数定义了本类型如何通过传值来传递对象。

新类型对合法数值有哪些限制? 通常情况下,只有一些数值的集合来限定类的数据成员是否合法。这些集合决定了类中需要维护哪些恒量。而这些恒量又决定着数据成员中要进行哪些错误检查,尤其是构造函数、赋值运算符、以及“调节”函数。它们还会影响到函数会抛出什么样的异常,同时,是否应用这些集合,还会影响到函数异常的详细内容。

新类型是否适用于继承? 如果新类是由现成的类继承而来的,那么就必须让新类符合继承的特征。尤其是要确定父类的成员函数是否应为虚函数(参见第 34 和第 36 条)。如果期望让其 它的类可以继承本类 ,就需要考虑本类的成员函数是否应为虚函数,尤其是它的析构函数(参见第 7 条)。

新类型允许进行哪些类型转换? 新的类型存在于其它类型的海洋中,那么是否应该提供新类型与其它类型的转型功能呢?如果你期望为 T1 的一个对象提供途径从而隐式将类型转换为 T2 。可以 通过在 T1 类中放置一个类型转换函数(比如 operator T2 ),或者在 T2 类中放置一个有单一参数的非 explicit 造函数。如果你仅仅期望允许显式类型转换,就需要编写函数来执行这一转换,但是这一函数不应是类型转换运算符,也不应是 单一参数的非 explicit 造函数。(第 15 条中有隐式 / 显式转换函数的示例。)

哪些运算符和函数对新类型是有意义的? 这个问题的答案取决于你会为你的类生命哪些函数。一些函数将成为成员函数,而一些则不会(参见第 23 24 46 条)。

应明确拒绝哪些标准函数? 通过将它们声明为 private 的可达到这一目的(参见第 6 条)。

谁可以访问新类型中的数据成员? 这一问题可以帮助我们确定哪些成员应声明为 public 的,哪些是 protected ,哪些是 private 。同时,也可以帮助我们确定哪些类和 / 或函数应该是友元,还有类的嵌套是否有意义。

新类型中有哪些“尚未声明的接口”? 新类型中提供了哪些性能、异常安全(参见第 29 条)、资源使用的保证(比如互斥锁、动态内存)?这些保证将会为类的实现提供更严格的约束。

新类型有多通用? 可能你想做得并不是定义一个新类型。而是定义一新类型。如果真是这样,你需要定义一个新的类模板

这个新类型是否满足了需求? 如果你创建新的派生类仅仅为了为现有的类添加新的功能,那么通过简单地定义一个或多个非成员函数或者模板可能会更好的达到目标。

完整地回答以上的问题并不是一件简单的事情,所以定义高效的类就是一项严峻的挑战。然而,如果成功经受了这一挑战,那么由用户自定义的类产生的类型至少可以像内建数据类型一样好用。一切都是值得的。

牢记在心

class 设计就是类型的设计。在定义一个新的类型之前,要确保将上面所有的问题考虑周全。


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理