关于构造函数的那点事

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37964547/article/details/82012626

在C++中,类模块有一个很重要的成员函数—-构造函数

什么是构造函数?

构造函数(constructor)是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。构造函数的功能主要用于在类的对象创建时定义初始化的状态。

构造函数的作用是什么?

构造函数主要用来在创建对象时完成对对象属性的一些初始化等操作, 当创建
对象时, 对象会自动调用它的构造函数。一般来说, 构造函数有以下三个方面
的作用:

  • 给创建的对象建立一个标识符;
  • 为对象数据成员开辟内存空间;
  • 完成对象数据成员的初始化。

为什么构造函数不能声明为const类型?

要理解这个问题,我们首先需要知道

  • const修饰的函数的返回值是const类型的,该返回值只能赋给同为const类型的变量
  • const是可以修饰类的成员函数,但是该函数不能修改数据成员。构造函数也属于类的成员函数,但是构造函数是要修改类的成员变量,所以类的构造函数不能申明成const类型的。

为什么构造函数不能声明为虚函数?

理解这个可以从以下方面来进行分析:

(1)从存储空间来分析

虚函数有一个vtable,并且vtable其实是存储在对象的内存空间的,问题出来了,如果构造函数是虚函数,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,无法找到vtable,所以构造函数不能是虚函数。

(2)从使用角度

  • 虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀。所以构造函数没有必要是虚函数。

  • 虚函数的作用在于通过父类的指针或者引用来调用它的时候能够变成调用子类的那个成员函数。而构造函数是在创建对象时自动调用的,不可能通过父类的指针或者引用去调用,因此也就规定构造函数不能是虚函数。

(3)从实现上来看

  • vtable在构造函数调用后才建立,因而构造函数不可能成为虚函数
  • 从实际含义上看,在调用构造函数时还不能确定对象的真实类型(因为子类会调父类的构造函数);而且构造函数的作用是提供初始化,在对象生命期只执行一次,不是对象的动态行为,也没有太大的必要成为虚函数

关于构造函数调用的问题

  • 当一个构造函数被调用时,它做的首要的事情之一是初始化它的V P T R。因此,它只能知道它是“当前”类的,而完全忽视这个对象后面是否还有继承者。 当编译器为这个构造函数产生代码时,它是为这个类的构造函数产生代码- -既不是为基类,也不是为它的派生类(因为类不知道谁继承它)。
  • 所以它使用的V P T R必须是对于这个类的V TA B L E。而且,只要它是最后的构造函数调用,那么在这个对象的生命期内, V P T R将 保持被初始化为指向这个V TA B L E, 但如果接着还有一个更晚派生的构造函数被调用,这个构造函数又将设置V P T R指向它的 V TA B L E,等直到最后的构造函数结束。V P T R的状态是由被最后调用的构造函数确定的。这就是为什么构造函数调用是从基类到派生类顺序的另一个理由。
  • 但是,当这一系列构造函数调用正发生时,每个构造函数都已经设置V P T R指向它自己的 V TA B L E。如果函数调用使用虚机制,它将只产生通过它自己的V TA B L E的调用,而不是最后的V TA B L E(所有构造函数被 调用后才会有最后的V TA B L E)。

猜你喜欢

转载自blog.csdn.net/qq_37964547/article/details/82012626