Effective C++ 条款34 区分接口继承和是实现继承

1. C++对于函数成员的继承主要有三种:

只继承接口,不继承实现;

同时继承接口和实现,同时允许覆写实现;

继承接口和实现,同时不允许对实现进行覆写.

2. 对于public继承,成员函数的接口应该总是被继承(由于is-a关系的存在),其中:

pure-virtual函数的目的只是为了使派生类继承函数接口;

impure-virtual(虚但非纯虚)函数的目的是既允许派生类继承接口和实现,又可以重写实现.

non-virtual函数的目的是令派生类继承函数的接口以及一份强制实现.(如果想要重写,那么之前就应该设为virtual函数)

public继承中,基类成员函数的种类应该遵循以上原则定义.

3. virtual函数既允许继承实现又允许重写实现的目的有时候会带来危险性,例如:

class Base{
public:
    virtual fun(){...}
    ...
private:
    ...
}
class Derived:public Base{
public
    ...
private:
    ...
}

Derived忘记定义自己的fun函数,因此默认继承Base的fun函数,这有可能是程序员不想要的结果,为了防止以下结果,可以将fun函数设为protect函数并命名为defaultFun以指明它是缺省实现,要使用缺省实现,就在fun中显示调用defaultFun函数,如下:

class  Base{
public:
    virtual void fun()=0;
    ...
protect:
    void defaultFun(){...}
    ...
private:
   ...
}
Derived:public Base{
public:
    virtual void fun{
        defaultFun();
    }
...
private:
    ...
}
   

由于fun函数在Base中被设为pure-virtual,因此Derived必须提供自己的定义,而它可以主动使用Base提供的defaultFun函数作.这样既通过pure-virtual的fun函数实现了只继承接口的功能,又通过non-virtual的defaultFun函数提供了一份使用default版本的选择.(defaultFun设为protect的目的是提高尽可能高的封装性)

除了使用以上将接口与实现分离的方法,还可以采用为Base的pure-virtual函数fun提供定义的方式,即:

class Base{
public:
    virtual void fun()=0;
    ...
private:
    ...
}
void Base::fun(){
    ...
}

Derived必须对fun函数进行实现,但如果想使用default实现,可以如以下定义:

class Derived:public Base{
public:
    virtual void fun(){
        Base::fun();
    }
    ...
private:
    ...
}

时间: 2025-01-02 15:05:34

Effective C++ 条款34 区分接口继承和是实现继承的相关文章

Effective C++ Item 34 区分接口继承与实现继承

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 关联条款 Item 36 接口继承和实现继承不同.在 public 继承下, derived classes 总是继承 base class 的接口 class Shape{ public: virtual void draw() const = 0; virtual void error(const std::string &msg); int objectID() const; //.

条款36: 区分接口继承和实现继承

作为类的设计者,有时希望派生类只继承成员函数的接口(声明):有时希望派生类同时继承函数的接口和实现,但允许派生类改写实现:有时则希望同时继承接口和实现,并且不允许派生类改写任何东西. class Shape { public: virtual void draw() const = 0; virtual void error(const string& msg); int objectID() const; ... }; class Rectangle: public Shape { ... }

More Effective C++ 条款34 如何在一个程序中结合C++和C

1. C++和C混合使用的前提之一就是编译器产生兼容的目标文件(.lib和.dll等).所谓"兼容",指的是编译器在"预编译器相依的特性上"一致,如int和double大小,参数压栈机制等,只有在这个基础上才能讨论结合使用C++和C模块的问题. 2. 在1的基础上,要结合使用C++和C的模块,主要有以下几点需要注意: 1). name mangling(名称重整) Name mangling是C++用于支持函数重载的机制,它对重载的函数名称进行一定改变,使得每个函数

Effective C++ 34 区分接口继承和实现继承

public继承从根本上讲,有两部分:接口继承和实现继承.两者之前的区别很像函数声明与函数定义. 具体设计中,会呈现三种形式:derived class只继承成员函数的接口(纯虚函数):derived class同时继承函数的接口和实现,同时能够重写(override):derived class同时继承函数的接口和实现,但是不允许重写该函数. 1.只继承成员函数的接口(纯虚函数): 例如pure函数 2.同时继承函数的接口和实现,同时能够重写(override): 例如impure函数,为了避

Effective C++ 条款39 明智而审慎地使用private继承

1. public继承表明is-a的关系,要求接口的完全继承,而private继承表明"根据某物实现出的关系",要求仅仅继承实现,private继承有两个规则: 1). 经由private继承而来的基类的所有成员在派生类中都会变成private属性 2). 由于1),编译器不允许将派生类转为基类以防止对派生类private成员的非法访问. 2. 由条款38,private继承和复合具有相同作用——"根据某物实现出".两者之间,要尽可能使用复合,除非必要情况.必要情况

《Effective C++》之条款34:区分接口继承和实现继承

<Effective C++> 条款34:区分接口继承和实现继承 Public继承由两部分组成 函数接口继承 函数实现继承 三种可能面对的继承 derived class 只继承成员函数的接口 derived class 同时继承函数的接口和实现,但又希望能够覆写它们所继承的实现 derived class 同时继承函数的接口和实现,但不允许覆写任何东西 总结: 接口继承和实现继承不同.在public继承下,derived classes 总是继承base class 的接口. Pure vi

Effective C++:条款34:区分接口继承和实现继承

(一) class Shape { public: virtual void draw() const = 0; virtual void error(const string& msg); int objectID() const; }; class Rectangle : public Shape {...}; class Ellipse : public Shape {...}; 公有继承的概念看似简单,似乎很轻易就浮出水面,然而仔细审度之后,我们会发现公有继承的概念实际上包含两个相互独立

《Effective C++》:条款34:区分接口继承和实现继承

public继承的概念,由2部分构成:函数接口(function Interface)继承和函数实现(function implementation)继承.这两种继承的差异有点像函数的声明和函数的定义之间的差异. 我们在设计class时,有时希望derived class只继承函数的接口(即函数声明):有时候希望derived class继承函数接口和实现,但又覆写它们所继承的实现:又有时候希望derived class同时继承函数的接口和实现,但不覆写任何东西. 为了更好理解上述差异,用一个绘

条款34:区分接口继承和实现继承(Different between inheritance of interface and inheritance of implemenation)

NOTE: 1.接口继承和实现继承不同.在public继承之下,derived classes总是继承base class的接口. 2.pure virtual 函数只具体指定接口继承及缺省实现继承. 3.impure virtual 函数具体指定接口继承及缺省实现继承. 4.non-virtual 函数具体指定接口继承及强制实现继承.