虚函数与纯虚函数

ifndef bmw_h #define bmw_h

class W {   public:     virtual void f(void) = 0;//纯虚函数=0

    virtual void g(void) = 0; //纯虚函数

    virtual void h(void) = 0;

    virtual void k(void);//虚函数

};

class MW : public virtual W {

  public:     virtual void g(void);//派生类重写函数g(void)

};

class BW : public virtual W {

  public:     virtual void f(void);

};

class BMW: public BW, public MW, public virtual W {

  public:     virtual void h(void); };

虚函数的作用是:在基类和派生类中,若基类和派生类具有相同的函数(返回值类型不构成多态,但参数要相同),无论此时声明谁的对象(基类或派生类),基类的函数的实现都会覆盖派生类的实现,这个时候只要将基类,(或基类和派生类同时)声明为虚函数,可消除此种现象

引入纯虚函数的意义:在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理

在许多情况下,基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类派生类去做。这就是纯虚函数的作用。

纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。

#include <stdio.h> #include "bmw.h"

extern void gg();  // Defined in bmw1.c to force a second copy of the

                   // vtables for BMW to be generated. Later eliminated

                   // by armlink.

void g(BMW *pbmw) {    

  pbmw->f();     // should be BW::f():

     pbmw->g();     // should be MW::g();

      pbmw->h();     // should be BMW::h();

      pbmw->k();     // should be W::k(); }//虚函数调用规则体现

void h(BMW *pbmw)

{     MW *pmw = pbmw;

    pmw->f();      // should be BW::f()... }//指针赋值之后调用规律

BMW bmw;

static char *bw = (char *)&bmw.__B_BW;   // This exploits the implementation

static char *mw = (char *)&bmw.__B_MW;   // and is not portable C++...

static char *pw = (char *)&bmw.__V_W;//指针赋值操作

void MW::g(void) {

    printf("MW::g(), this %s mw\n", (char *)this == mw ? "==" : "!="); }//类似与断言assert、==

void BW::f(void) {

    printf("BW::f(), this %s bw\n", (char *)this == bw ? "==" : "!="); }//==

void BMW::h(void) {

    printf("BMW::h(), this %s bmw\n",(char *)this == (char *)&bmw ? "==" : "!="); }//==

void W::k(void) {     printf("W::k(), this %s pw\n", (char *)this == pw ? "==" : "!="); }//==

int main() {

    printf("\nExpected output from g():\n\

            BW::f(), this == bw\n\

            MW::g(), this == mw\n\  

           BMW::h(), this == bmw\n\

            W::k(), this == pw\n");

    printf("........calling g()........\n");

    g(&bmw);

    printf("\nExpected output from h():\n\BW::f(), this == bw\n");

    printf("........calling h()........\n");

    h(&bmw);  

   printf("\nExpected output from gg():\n\

            BW::f(), this != bw\n\

            MW::g(), this != mw\n\

            BMW::h(), this != bmw\n\

            W::k(), this != pw\n");

    printf("........calling gg()........\n");

    gg();

    return 0; }

posted @ 2015-05-13 10:37  高傲的monkey  阅读(170)  评论(0编辑  收藏  举报