C++编程规范之39:考虑将虚拟函数生命为非公用的,将公用函数声明为非虚拟的
2014-01-01 12:59
274 查看
摘要:
在基类中进行修改代码高昂:请将公用函数设为非虚拟的。应该将虚拟函数设为私有的,或者如果派生类需要调用基类版本,则设为保护的。
在面向对象层次结构中进行修改是昂贵的,所以应该实施完整的抽象:将公用函数设为非虚拟的,将虚拟函数设为私有的。这就是所谓的非虚拟接口模式。
公用虚拟函数本质上有两种不同而且互相竞争的职责,针对的是两种不同而且互相竞争的目标:
1.它制定了接口。作为公用函数,它是类向外界提供的接口的一部分。
2.它制定了实现细节。作为虚拟函数,它为派生类替换函数的基类实现提供了一个钩子,它是一个自定义点。
因为这两种职责的动机和目标都不同,所以它们可能会发生冲突,因而从定义上来讲一个函数无法很好地履行两种职责。公用虚拟函数本身有两种on革命性不同的职责和两种互相竞争的目标,这是没有很好地将问题关注点分离的标志。
通过将公用函数与虚拟函数分离,可以获得如下明显的好处。
1.每个接口都能自然成形。将公用函数与自定义接口分离后,每个接口都能很容易地获得符合其自然需求的形式,而不用寻找折中方案,以使他们看上去相同。两个接口经常需要不同数量的函数或不同的参数。
2.基类拥有控制权。基类现在完全控制着其接口和策略,可以实时接口的前后置条件、插入度良性代码,还可以在一个方便的可重用场所中做任何类似的工作。因此,这种为了分离而进行的“预构“能够促进良好的类设计。
3.基类能够健壮地适应变化。以后,我们可以随意改变构思、添加前后条件检查,或者将处理工作分成更多步骤,或者进行重构,或者用Pimpl惯用法实现更完整的接口与实现的分离,或者对基类的可自定义性进行其他修改,而不会影响到使用此类或者从此类继承的任何代码。
在基类中进行修改代码高昂:请将公用函数设为非虚拟的。应该将虚拟函数设为私有的,或者如果派生类需要调用基类版本,则设为保护的。
在面向对象层次结构中进行修改是昂贵的,所以应该实施完整的抽象:将公用函数设为非虚拟的,将虚拟函数设为私有的。这就是所谓的非虚拟接口模式。
公用虚拟函数本质上有两种不同而且互相竞争的职责,针对的是两种不同而且互相竞争的目标:
1.它制定了接口。作为公用函数,它是类向外界提供的接口的一部分。
2.它制定了实现细节。作为虚拟函数,它为派生类替换函数的基类实现提供了一个钩子,它是一个自定义点。
因为这两种职责的动机和目标都不同,所以它们可能会发生冲突,因而从定义上来讲一个函数无法很好地履行两种职责。公用虚拟函数本身有两种on革命性不同的职责和两种互相竞争的目标,这是没有很好地将问题关注点分离的标志。
通过将公用函数与虚拟函数分离,可以获得如下明显的好处。
1.每个接口都能自然成形。将公用函数与自定义接口分离后,每个接口都能很容易地获得符合其自然需求的形式,而不用寻找折中方案,以使他们看上去相同。两个接口经常需要不同数量的函数或不同的参数。
2.基类拥有控制权。基类现在完全控制着其接口和策略,可以实时接口的前后置条件、插入度良性代码,还可以在一个方便的可重用场所中做任何类似的工作。因此,这种为了分离而进行的“预构“能够促进良好的类设计。
3.基类能够健壮地适应变化。以后,我们可以随意改变构思、添加前后条件检查,或者将处理工作分成更多步骤,或者进行重构,或者用Pimpl惯用法实现更完整的接口与实现的分离,或者对基类的可自定义性进行其他修改,而不会影响到使用此类或者从此类继承的任何代码。
相关文章推荐
- 警告:隐式声明与内建函数'exit'不兼容解决方案
- 警告:隐式声明与内建函数'exit'不兼容解决方案
- 警告:隐式声明与内建函数'exit'不兼容解决方案
- 虚拟函数:在基类中被声明为virtual,而在派生类中又重新定义了这个函数
- C怎样定义和声明全局变量和函数最好?
- 查看正在运行的动态链接的程序中,某个动态库中函数的虚拟地址
- 条款35:考虑virtual函数以外的其他选择(Consider alternative to virtual functions)
- 变量声明提升和函数声明提升
- 5章1节函数的声明定义用法
- JavaScript中函数声明优先于变量声明
- C++箴言:多态基类中将析构函数声明为虚拟zz
- 函数声明和表达式
- 记得适当的声明成员函数为const.
- 39 WebGL着色器和着色器程序对象:initShader()函数的作用
- php学习笔记之 函数声明(二)
- 【1】Windows客户端C/C++编程规范“建议”——函数
- C++中的const成员函数(函数声明后加const,或称常量成员函数)用法详解
- 声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*,正确的是()
- JavaScript 中对变量和函数声明的“提前(hoist)”