C++继承中析构函数 构造函数的调用顺序以及虚析构函数

首先说说构造函数。大家都知道构造函数里就能够调用成员变量,而继承中子类是把基类的成员变成自己的成员,那么也就是说子类在构造函数里就能够调用基类的成员了,这就说明创建子类的时候必须先调用基类的构造函数,仅仅有这样子类才干在构造函数里使用基类的成员,所以是创建子类时先调用基类的构造函数然后再调用自己的构造函数。通俗点说,你要用某些物品。但这些物品你没办法自己生产,自然就要等别人生产出来,你才干拿来用。

接着就是析构函数了,上面说到子类是将基类的成员变成自己的成员,那么基类就会仅仅存在子类中直到子类调用析构函数后。做个如果:假如在基类的析构函数调用比子类的先。这样会发生什么事呢?类成员终止了,而类本身却还在,可是在类存在的情况下。类成员就应该还存在的,这不就产生矛盾了吗?所以子类是调用自身的析构函数再调用基类的析构函数。基类的析构函数必须设置为虚的,而作为终于子类则能够是虚的也能够不是虚的,由于没有其它类继承于它不会影响终于功能。但又不是全部类的析构函数都设置为虚的比較好。由于存在虚函数的类实例化时会额外加入一个虚表指针。浪费内存性能。

如今到了虚函数了。virtual主要作用是在多态方面,而C++的多态最基本的是类的动态绑定,动态绑定则是指将子类的指针或引用转换成基类,基类对象就能够动态推断调用哪个子类成员函数。

这就说明在没有子类指针或引用转换为基类对象的话。virtual没有存在意义(纯虚函数除外)。也就是有没有virtual都是调用其自身的成员函数。通过这些分析,对于virtual就有了眉目了。

当子类指针或引用转换为基类时,若基类中实用virtual定义的函数,被子类重写后。此基类对象就会依据子类调用子类中的重写后的函数,而不是基类中的函数;反之,若是基类中没实用virtual定义,则无论基类被赋值的是哪个子类的值,调用的都是基类的成员函数(当然指的值子类重载的基类函数,不然就算要调用子类特有的成员函数也会编译只是)。

存在虚析构函数为什么不会存在虚构造函数呢?

构造函数不能是虚函数,由于构造子类时本身也是调用的子类构造函数,然后子类构造函数会调用基类构造函数。所以虚构造函数的存在是没有意义的。

仅仅有在构造完毕后,对象才干成为一个类的名符事实上的实例。

另外,静态成员函数和内联函数也不能是虚函数。

虚函数是针对对象的,不是针对类的.

这一点能够从类成员函数(即静态成员函数)不能是虚函数看出来.倘若类不被实例化为对象,虚函数的存在本身也没意义.

上面的如果我感觉并不认可,派生类中的构造,析构能够调用到基类的构造析构是由编译器编译中实现的.即:在子类构造函数开头自己主动加入默认的基类构造函数或初始化列表中指定的基类构造函数调用;在子类析构函数末尾自己主动加入其基类析构函数调用.

至于为什么会先调用基类构造函数再调用子类构造函数,先调用子类析构函数再调用基类析构函数.我觉得:由于仅仅可能出现子类中成员依赖基类成员的存在而存在,而不会出现基类中成员依赖子类成员存在.比如:子类中有一个成员是基类中一个指针成员所指向对象的引用.则这样的情况下倘若没有先调用基类构造函数对其指针成员初始化创建对象.那子类引用初始化时便不知会指向何处.相同析构时倘若先调用基类将当中的对象释放后,此时子类中引用变量在做一下善后处理时也便没有不论什么意义,因而其指向对象已经释放掉了.
派生类对象中基类成员先于子类成员存在,后于子类对象消失.

时间: 2024-08-05 13:53:55

C++继承中析构函数 构造函数的调用顺序以及虚析构函数的相关文章

C++多重继承,菱形继承中构造函数的调用顺序

C++中多重继承不免会出现钻石继承,也就是继承类的两个基类同时又是同一个基类的继承类,当创建一个对象的时候,他们是按照什么样的顺序调用构造函数的呢. 如果不进行虚拟继承: class Base { public: Base() { cout<<"Base默认构造函数调用"<<endl; } Base(int i) { cout<<"Base参数构造函数调用"<<endl; cout<<i<<en

(C++)C++类继承中的构造函数和析构函数

思想: 在C++的类继承中, 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时,其顺序正好与构造相反: 例子: #include <iostream> using namespace std; class Shape{ public: void Draw() {cout<<"Base::Draw()"<<endl;} void Erase() {cout<<"Base::Erase()

继承中的构造析构函数调用顺序

子类构造函数必须堆继承的成员进行初始化: 1. 通过初始化列表或则赋值的方式进行初始化(子类无法访问父类私有成员) 2. 调用父类构造函数进行初始化 2.1  隐式调用:子类在被创建时自动调用父类构造函数(只能调用父类的无参构造函数和使用默认参数的构造函数) 2.2  显示调用:在初始化列表调用父类构造函数(适用所有的父类构造函数) #include <iostream> #include <string> using namespace std; class PParent //

JAVA继承中的构造函数

ps:因为顺口...我喜欢把方法称为函数 1) 一个单独的类,如果没有声明任何构造函数,那么系统会自动生成一个无参的构造函数,此时,new classA() 不会报错. ! 如果显式声明了一个有参构造函数,再使用 new classA(无参) 将会报错,因为在已有情况下系统不会帮助生成无参构造,建议自己添加一个无参构造函数 ---一个类的构造函数只会有三种状况:无参    /   无参+有参    /   有参 2) 如果存在继承关系,假设classB extends classA , 子类的所

继承中的构造函数

构造函数的作用:初始化对象, 继承的两个特性:单根性,和传递性. 一:一个类中可以存在多个构造函数,他们实现一个重载关系.构造函数之间会造成冗余的情况. 列如: 解决办法就是用this来解决冗余问题. this 有两个作用:1.表示当前类的对象.2.解决本类中出现的冗余问题. 二:继承中构造函数. 继承:即子类(派生类)继承父类(基类)的属性和方法,在这个过程中发生的过程: 1.为子类实例化对象时,系统会默认为父类实例化对象,(默认调用的是空构造函数)调用父类的属性和方法,然后才实例化子类对象.

组合类的构造函数的调用顺序

文章来源:https://bbs.csdn.net/topics/390253882 “构造函数调用顺序:先调用内嵌对象的构造函数(按内嵌时的声明顺序,先声明者先构造).然后调用本类的构造函数.(析构函数的调用顺序相反)” #include<iostream> using namespace std; class Part //部件类 { public: Part() {cout<<"Part default construction called"<&l

C++中复制构造函数被调用的三种情况

C++中的构造函数 c++中的构造函数分为构造函数,和复制构造函数,相比于构造函数,复制构造函数使用更加方便,快捷.构造函数可以有多个,二复制构造函数只能有一个,因为复制构造函数的参数只能是当前类的一个对象,参数表是固定的,无法重载,若用户没有定义自己的辅助构造函数,系统会自动生成一个复制构造函数,其作用是将参数的之赋予当前的对象.若用户自己定义了复制构造函数,系统则不会生成默认复制构造函数.用户自己定义的复制构造函数功能可以自己构造,不一定执行复制的功能. 复制构造函数同构造函数的功能大体相同

继承构造函数的调用顺序

子类构造方法在调用时必须先调用父类的,由于父类没有无参构造,必须在子类中显式调用,修改子类构造方法如下即可: public Derived(String s){         super("s");         System.out.print("D");     } 在调用子类构造器之前,会先调用父类构造器,当子类构造器中没有使用"super(参数或无参数)"指定调用父类构造器时,是默认调用父类的无参构造器,如果父类中包含有参构造器,却没

【TOJ 5254】C++实验:继承中的构造函数和析构函数

描述 实现C++类Base和Derived,并编写相关构造函数和析构函数,使其能够输出样例信息. 主函数里的代码已经给出,请补充完整,提交时请勿包含已经给出的代码. int main() { Base *p = new Derived(1, 2); delete p; Base b; Derived d; return 0; } 输入 无 输出 输出样例信息. 样例输入 无 样例输出 Base Constructor 1Derived Constructor 2Derived Destructo