C++ 类层次结构的设计方法学(2)

这里 Diamond-shaped Inheritance 钻石形继承的意义:让实现 PopupIValSlider 的类(即 BBPopupIValSlider)共享实现 IValSlider 的类(即 BBIValSlider)中的实现,以减少编码

于是另一个有意思的推论:组成应用之接口的抽象类的所有派生都应该是 virtual 的,[EFFECT CPP] Item 40 也说 public 继承应该总是 virtual
但是现实不能如此,最简短的反驳是效率因素,见 [CPP LANG] 15.2.5 和 [EFFECT CPP] Item 40

可藉由无 data member class 进行重复基类方式的优化
于是,饶了一圈又回来了

抽象工厂^

构造函数不可能是 virtual 的,道理很简单:不知道对象的确切类型,又如何构造它(构造函数的实质是对象内布局的 bits 初始化)

抽象工厂和 Clone 模式被戏称为 virtual constructor 虚拟构造函数,因为它们用 virtual 函数迂回完成构造函数的任务:根据某些线索创建对象

对于真的构造函数,线索是构造函数之参数 对于抽象工厂,线索是程序初始化时的预先设置。它的形态(典型的)可以是类的 UUID 标识 (e.g. COM's IClassFactory) 对于 Clone 模式,线索是当前对象之确切类型

绝对的抽象创建(没有线索)是不可能的,即没有语法支持(virtual 构造函数),也没有逻辑意义:当你想要铅笔时,可以说我要铅笔,也可以说我要铅笔盒中的东西(带线索的抽象),但不能只说我要东西(不带线索的抽象)

Why abstract class?

UML: Abstract Factory

C++ 类层次结构的设计方法学

减小对象创建时,对特定实现类(构造函数)的依赖,如当创建 IValDial 时,必须使用 BBIValDial 或 LSIValDial 的构造函数

当抽象类层次结构较复杂时,并且有从一个实现系统变为另一个实现系统(如从 BBWindow 变为 LSWindow)的预期时,需要一种一次性装入实现系统中各种创建对象的方法,这时抽象工厂就会发挥作用:

创建具体工厂类对象 将具体工厂类对象装入抽象工厂类对象(引用、指针) 用抽象工厂类对象创建抽象构造块类 使用抽象构造块类的方法,它动态绑定到具体构造块类的方法

1、2 是程序初始化阶段执行的设置,3、4 是程序例行阶段的行为

于是,抽象工厂是和抽象类层次伴生的

Clone 模式^

UML: Clone Pattern

C++ 类层次结构的设计方法学

Why clone?

手上有一个对象,只知道它的抽象类型(确切类型已丢失),要复制这种对象的大量副本,并且副本要和其确切类型一致

可以定义一个 Clonable 抽象基类,以规约 clone 函数,但不是必须的

Clone 模式可从函数 override 的返回值类型的 covariance 协变中受益。VC 2005+ 支持协变

参考书籍^ [CPP LANG] "The C++ Programming Language, Special Ed", Bjarne Stroustrup [EFFECT CPP] "Effective C++, 3Ed", Scott Meyers [CPP PRIMER] "C++ Primer, 3Ed", Stanley Lippman, Josee Lajoie [CPP OBJMODEL] "Inside The C++ Object Model", Stanley Lippman

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ppdps.html