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 ", (char *)this == mw ? "==" : "!="); }//类似与断言assert、==
void BW::f(void) {
printf("BW::f(), this %s bw ", (char *)this == bw ? "==" : "!="); }//==
void BMW::h(void) {
printf("BMW::h(), this %s bmw ",(char *)this == (char *)&bmw ? "==" : "!="); }//==
void W::k(void) { printf("W::k(), this %s pw ", (char *)this == pw ? "==" : "!="); }//==
int main() {
printf(" Expected output from g():
BW::f(), this == bw
MW::g(), this == mw
BMW::h(), this == bmw
W::k(), this == pw ");
printf("........calling g()........ ");
g(&bmw);
printf(" Expected output from h(): BW::f(), this == bw ");
printf("........calling h()........ ");
h(&bmw);
printf(" Expected output from gg():
BW::f(), this != bw
MW::g(), this != mw
BMW::h(), this != bmw
W::k(), this != pw ");
printf("........calling gg()........ ");
gg();
return 0; }