您的位置:首页 > 编程语言 > C语言/C++

C++总结之继承和面向对象的设计

2010-08-07 12:48 645 查看
继承和面向对象设计是C++的高级特性,需要长期的积累才能领悟。这里只是根据effective C++条目进行的梳理,顺序有所调整,根据自身不成熟的认知来进行的过滤,已备后用。

 

公有(public)继承注意事项
1.“public继承”意味着is-a的关系。
适用于base classes身上的每一件事情也一定适用于derived classes身上,因为每一个derived classes对象也是一个base classes对象。
2.derived classes内的名称会遮掩base classes内的名称。
在public继承下从来没有人希望如此。
3.为了让被遮掩的名称再现,可以使用using声明式或转交函数。
如下:
class Base{
private:
   int x;
public:
   virtual void mf1() = 0;
   virtual void mf1(int) = 0;
   virtual void mf2();
   ----
};
class Derived : public Base{
public:
   using Base::mf1;
   using Base::mf2;
   virtual void mf1();
   void mf4();
   ---
};

使用转交函数
class Derived : public Base{
public:
   virtual void mf1()
   {
        Base::mf1();
   }
   ---------
};
4.不要重新定义继承而来的non-virtual函数。
因为non-virtual函数是静态绑定的,同时也指定了derived必须同时继承它的接口和实现,所以如果继承了non-virtual函数而需要修改它,那么我们是不是要考虑这个设计是否合理?如果非要修改,请把该函数声明为virtual。
5.不要重新定义一个继承而来的缺省参数值。
因为缺省参数值都是静态绑定的,而virtual函数,我们唯一应该覆写的东西却是动态绑定的。如果需要请找替代方案。

复合和私有继承
1.复合(composition)的意义和public继承完全不同。
复合是has-a的关系,而public继承则是is-a的关系。
2.在应用领域,复合意味 has-a,而在实现领域,复合意味着is-implemented-terms-of(根据某物实现出来)。
3.private继承意味着is-implemented-terms-of。
它通常比复合的级别低。但是当derived class需要访问protected base class的成员时,或需要重新定义继承而来的virtual函数时,这个设计是合理的。
4.private继承可以造成empty base的最优化,这点和复合是不同的。
这对于致力于“对象尺寸最小化”的程序库开发者而言,可能很重要。

接口继承和是实现继承
1.接口继承和实现继承是不同的。
在public继承体系下,derived class总是继承base class的接口。
2.纯虚函数(pure virtual functions)只具体指定接口继承。
如下:
class Shape{
public:
  virtual void draw() = 0;
  ---

 

};
3.一般虚函数(impure virtual functions)具体指定接口继承以及缺省实现继承。
如下:
class Shape{
public:
  virtual void log(const std::string &logFileName);
  ---

};
3.non-virtual函数具体指定接口继承以及强制性实现继承。
如下:
class Shape{
public:
   virtual ~Shape();
   unsigned int objectID() const;

   ------

};

虚函数(virtual functions)以外的替代方案
1.虚函数的替代方案包括NVI(non-virtual interface)手法以及Strategy设计模式的多种形式。

NVI手法自身是一个特殊形式的Template Method设计模式。
2.将机能从成员函数移到class外部函数。
如此将会带来缺点,非成员函数无法访问class的non-public成员。
3.tr1::function对象的行为就像一般的函数指针。
这样的对象可接纳“与给定的目标标签名式兼容”的所有可以调用物。

关于多重继承
1.多重继承比单一的继承复杂。
它可能导致新的歧义性,以及对virtual继承的需要。
2.virtual继承会增加大小,速度,初始化(及赋值)复杂度等等成本。
如果virtual base classes不带任何数据,将是最具实用价值的情况。
3.多重继承的确有正当用途。
其中一个情节涉及“public继承某个interface class”和“private继承某个协助实现的class”的两相组合。这个在大型系统架构中还是比较多的,我看到过好多了。

条目主线:Effective C++ Third Edition

转载请注明出处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息