1. 关于虚析构的认识大家好,我是 DongGu ,是一名软件工程专业大二的学生,写博客一方面是为了记录自己的学习过程,把自己犯的错误进行分享。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!有任何问题可以评论 或者 ___>
QQ联系(1521839703)
个人博客网站也搭好啦: dongguxy.top
先看上面3种情况,其实设不设为虚函数都没问题, 就是怕delete一个动态分配的对象,且动态类型为子类的时候,会出现指针的静态类型与被删除对象的动态类型不符合的情况
如果不为虚,会发生什么:
- 那么就会出现第三种情况,子类的析构函数不发生
- 普通函数都是静态绑定的,你这里的指针变量a是g类型,那么调用函数肯定是g里的方法
为什么要让父类的析构函数要设成虚的, 主要有一下方面:
2. 虚函数
- 我们都知道, 有了虚函数,就有了虚函数表,有了虚函数表,就会继承父类的虚函数表的内容,如果子类没有重写父类的虚函数方法,那么该函数地址不会变化,如果写了,那么就会更新虚函数表的函数地址,
- 然后我们又想,如果父类实现虚析构函数,子类没有实现怎么办? 我们要记住,如果父类有虚函数,系统会给我们实现一个默认构造函数,默认析构函数,默认拷贝构造函数,后面会讲,
- 调用虚函数的时候,就会读到虚函数表的地址,再通过偏移量去调用,因为虚函数表的函数位置是不变的,函数地址在编译前就确定了的
测试代码:
#include #includeusing namespace std; class Father { public: int fa; virtual ~Father(){} virtual void i() {} }; class Son:public Father{ public: int s; virtual void i() {} ~Son() {} }; int main() { Father* f = new Son; f->i(); f->Father::i(); f->fa = 10; delete f; return 0; }
- 多重继承下的虚函数,一图以蔽之
3. 虚基类测试代码:
#include #includeusing namespace std; class Father { public: int fa; virtual ~Father() { cout << "~Fathern"; } virtual void i() {} }; class Father2 { public: int fa2; virtual ~Father2() { cout << "~Father2n"; } virtual void j() {} virtual void k() {} }; class Son:public Father,public Father2{ public: int s; virtual void i() {} virtual void k() {} virtual ~Son() { cout << "~Sonn"; } }; int main() { Son* s = new Son; s->k(); Father* f = s; f->i(); f->fa = 10; Father2* f2 = s; f2->j(); f2->k(); f2->fa2 = 2; delete f2; return 0; }
- 虚继承父类,类中有虚函数
测试代码:
#include #includeusing namespace std; class B { public: int b; }; class B1 :public virtual B { public: int b1; virtual void fun() { cout << "B1 funn"; } }; int main() { B1* b1 = new B1; b1->b1 = 10; b1->b = 3; b1->fun(); return 0; }
虚继承父类,父类有虚函数
当一个类虚继承继承多个父类的时候
测试代码
#include #includeusing namespace std; class B { public: int b; }; class B1 :public virtual B { public: int b1; virtual void fun() { cout << "B1 funn"; } }; class B2 : public virtual B { public: int b2; }; class C { public: int c; }; class A :public B1, public B2, public C { public: int a; }; int main() { A a; a.b = 10; a.b1 = 3; a.b2 = 4; a.c = 5; a.a = 6; B1* b1 = new A; b1->b = 10; b1->b1 = 20; b1->fun(); return 0; }
- 多继承,都有虚函数时,就相当于,每个类中包含虚函数表,虚基类表,数据成员,如果子类有虚函数,那么该虚函数表和第一个父类共用一个虚函数表
总结测试代码如下:
#include #includeusing namespace std; class B { public: int b; }; class B1 :public virtual B { public: int b1; virtual void fun() { cout << "B1 funn"; } }; class B2 : public virtual B { public: int b2; virtual void fun1() { cout << "B1 funn"; } }; class C { public: int c; virtual void func() { cout << "c funn"; } }; class A :public B1, public B2, public C { public: int a; virtual void funa() { cout << "a funn"; } }; int main() { A *a = new A; a->b = 10; a->b1 = 3; a->b2 = 4; a->c = 5; a->a = 6; a->fun(); a->fun1(); a->func(); a->funa(); B1* b1 = new A; b1->b = 10; b1->b1 = 20; b1->fun(); B2* b2 = new A; b2->b = 10; b2->b2 = 20; b2->fun1(); return 0; }
虚函数怎么访问呢,虚基类怎么访问呢?
就是通过this指针移到该静态类型的首地址去,然后通过调用虚函数表,虚基类表取查找地址,再访问



