CPP

纯虚函数的作用和实现方式

2018-03-30  本文已影响276人  顽强的猫尾草

一、作用:

定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

应该在什么情况下使用纯虚函数?
  1、当想在基类中抽象出一个方法,且该基类只做能被继承,而不能被实例化;
  2、这个方法必须在派生类(derived class)中被实现。

二、实现方式:

纯虚函数的声明,是在虚函数声明的结尾加 = 0,没有函数体。在派生类没有重新定义虚函数之前是不能调用的。

举个例子,我们先定义一个形状类(Cshape),但凡是形状我们都要求其能显示自己。所以这个类定义如下:

class CShape
{
    virtual void Show() {};
};

但没有 CShape 这种形状,因此我们不想让 CShape 这个类被实例化,我们首先想到的是将 Show 函数的定义(实现)部分删除:

class CShape
{
    virtual void Show();
};

当我们使用下面的语句实例化一个 CShape 时:

CShape cs;    // 这是我们不允许的,但仅用上面的代码是可以通过编译(但 link 时失败)

怎么样避免一个 CShape 被实例化,且在编译时就能被发现?
答案是:使用虚函数。

我们再次修改CShape类如下:

class CShape
{
public:
    virtual void Show() = 0;
};

这时在实例化 CShape 时就会有以下报错信息:

error C2259: 'CShape' : cannot instantiate abstract class due to following members:
warning C4259: 'void __thiscall CShape::Show(void)' : pure virtual function was not defined

我们再来看看被继承的情况。我们需要一个 CPoint2D 的类,它继承自 CShape。他必须实现基类(CShape)中的 Show() 方法。
其实使用最初的本意是让每一个派生自 CShape 的类,都要实现 Show() 方法,但时常我们可能在一个派生类中忘记实现,为了避免这种情况,虚函数发挥作用了。

我们看以下代码:

class CPoint2D:public CShape
{
public:
    CPoint2D()
    {
        printf("CPoint2D ctor is invoked/n");
    };
    void Msg()
    {
        printf("CPoint2D.Msg() is invoked/n");
    };

    /*---I'm sorry to forget implement the Show()---
    void Show()
    {
        printf("Show() from CPoint2D/n");
    };
    ------------------------------------------------*/
};

当我们实例化 CPoint2D 时,在编译时也会出现如下的报错:

error C2259: 'CShape' : cannot instantiate abstract class due to following members:
warning C4259: 'void __thiscall CShape::Show(void)' : pure virtual function was not defined

如上,我们预防了在派生类中忘记实现基类方法。

上一篇 下一篇

猜你喜欢

热点阅读