本文关键词:C++ 多态 多继承 多重继承 虚函数表 虚函数指针 动态绑定
一、多态起手式以及内存分布
二、类的虚函数表与类实例的虚函数指针
首先不考虑继承的情况。如果一个类中有虚函数,那么该类就有一个虚函数表。
这个虚函数表是属于类的,所有该类的实例化对象中都会有一个虚函数表指针去指向该类的虚函数表。
从第一部分的图中我们也能看到,一个类的实例要么在堆上,要么在栈上。也就是说一个类可以有很多很多个实例。但是!一个类只能有一个虚函数表。在编译时,一个类的虚函数表就确定了,这也是为什么它放在了只读数据段中。

三、多态代码及多重继承情况
class ClassA { public: ClassA() { cout << "ClassA::ClassA()" << endl; } virtual ~ClassA() { cout << "ClassA::~ClassA()" << endl; } void func1() { cout << "ClassA::func1()" << endl; } void func2() { cout << "ClassA::func2()" << endl; } virtual void vfunc1() { cout << "ClassA::vfunc1()" << endl; } virtual void vfunc2() { cout << "ClassA::vfunc2()" << endl; } private: int aData; }; class ClassB : public ClassA { public: ClassB() { cout << "ClassB::ClassB()" << endl; } virtual ~ClassB() { cout << "ClassB::~ClassB()" << endl; } void func1() { cout << "ClassB::func1()" << endl; } virtual void vfunc1() { cout << "ClassB::vfunc1()" << endl; } private: int bData; }; class ClassC : public ClassB { public: ClassC() { cout << "ClassC::ClassC()" << endl; } virtual ~ClassC() { cout << "ClassC::~ClassC()" << endl; } void func2() { cout << "ClassC::func2()" << endl; } virtual void vfunc2() { cout << "ClassC::vfunc2()" << endl; } private: int cData; }; ClassA *a = new ClassB(); a->func1(); // "ClassA::func1()" 隐藏了ClassB的func1() a->func2(); // "ClassA::func2()" a->vfunc1(); // "ClassB::vfunc1()" 重写了ClassA的vfunc1() a->vfunc2(); // "ClassA::vfunc2()" 这个结果不难想象,看上图,ClassA类型的指针a能操作的范围只能是黑框中的范围,之所以实现了多态完全是因为子类的虚函数表指针与虚函数表的内容与基类不同
这个结果已经说明了C++的隐藏、重写(覆盖)特性。
ClassA* a = new ClassC; a->func1(); // "ClassA::func1()" 隐藏ClassB::func1() a->func2(); // "ClassA::func2()" 隐藏ClassC::func2() a->vfunc1(); // "ClassB::vfunc1()" ClassB把ClassA::vfunc1()覆盖了 a->vfunc2(); // "ClassC::vfunc2()" ClassC把ClassA::vfunc2()覆盖了 ClassB* b = new ClassC; b->func1(); // "ClassB::func1()" 有权限操作时,子类优先 b->func2(); // "ClassA::func2()" 隐藏ClassC::func2() b->vfunc1(); // "ClassB::vfunc1()" ClassB把ClassA::vfunc1()覆盖了 b->vfunc2(); // "ClassB::vfunc2()" ClassC把ClassA::vfunc2()覆盖了
四、多继承下的虚函数表 (同时继承多个基类)
多继承是指一个类同时继承了多个基类,假设这些基类都有虚函数,也就是说每个基类都有虚函数表,那么该子类的逻辑结果和虚函数表是什么样子呢?
class ClassA1 { public: ClassA1() { cout << "ClassA1::ClassA1()" << endl; } virtual ~ClassA1() { cout << "ClassA1::~ClassA1()" << endl; } void func1() { cout << "ClassA1::func1()" << endl; } virtual void vfunc1() { cout << "ClassA1::vfunc1()" << endl; } virtual void vfunc2() { cout << "ClassA1::vfunc2()" << endl; } private: int a1Data; }; class ClassA2 { public: ClassA2() { cout << "ClassA2::ClassA2()" << endl; } virtual ~ClassA2() { cout << "ClassA2::~ClassA2()" << endl; } void func1() { cout << "ClassA2::func1()" << endl; } virtual void vfunc1() { cout << "ClassA2::vfunc1()" << endl; } virtual void vfunc2() { cout << "ClassA2::vfunc2()" << endl; } virtual void vfunc4() { cout << "ClassA2::vfunc4()" << endl; } private: int a2Data; }; class ClassC : public ClassA1, public ClassA2 { public: ClassC() { cout << "ClassC::ClassC()" << endl; } virtual ~ClassC() { cout << "ClassC::~ClassC()" << endl; } void func1() { cout << "ClassC::func1()" << endl; } virtual void vfunc1() { cout << "ClassC::vfunc1()" << endl; } virtual void vfunc2() { cout << "ClassC::vfunc2()" << endl; } virtual void vfunc3() { cout << "ClassC::vfunc3()" << endl; } };
最后给出代码和结果
ClassA1 *a1 = new ClassC; a1->func1(); // "ClassA1::func1()" 隐藏子类同名函数 a1->vfunc1(); // "ClassC::vfunc1()" 覆盖父类ClassA1虚函数 a1->vfunc2(); // "ClassC::vfunc2()" 覆盖父类ClassA1虚函数 没有a1->vfunc3(),父类没有这个虚函数 ClassA2 *a2 = new ClassC; a2->func1(); // "ClassA2::func1()" 隐藏子类同名函数 a2->vfunc1(); // "ClassC::vfunc1()" 覆盖父类ClassA2虚函数 a2->vfunc2(); // "ClassC::vfunc2()" 覆盖父类ClassA2虚函数 a2->vfunc4(); // "ClassA2::vfunc4()" 未被子类重写的父类虚函数 ClassC *c = new ClassC; c->func1(); // "ClassC::func1()" c->vfunc1(); // "ClassC::vfunc1()" c->vfunc2(); // "ClassC::vfunc2()" c->vfunc3(); // "ClassC::vfunc3()" c->vfunc4(); // "ClassA2::func4()"
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/202003.html原文链接:https://javaforall.net
