构造函数虚函数的应用

面试管问你构造函数可以为构慥函数虚函数吗?如果你知道你可以勇敢的反问,能不要问这么简单的问题吗如果你不知道,请记住这个答案-----不能!

以下是copy一个CSDN大佬寫的博客刚好我是后者!

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

  2. 构慥函数虚函数主要用于在信息不全的情况下能够使重载的函数得到对应的调用。构造函数本身就是要初始化实例那使用构造函数虚函數也没有实际意义。
    另外构造函数虚函数的作用在于通过父类的指针或者引用来调用它的时候能够变成调用子类的那个成员函数,从而實现多态也就是实现“”。而构造函数是在创建对象时自动调用的不可能通过父类的指针或者引用去调用,因此规定构造函数不能是構造函数虚函数

高赞回答说的很不错但是不够詳细,我来补充一些

TLDR:构造函数可以是构造函数虚函数,例如 Delphi 就有这样的设计但是C++中构造函数不能是构造函数虚函数。

从C++的视角来看我们只能在编译时明确我们要构造的类的类型,才可以拿到这个类的构造函数再使用这个构造函数构造我们想要的类,虚的构造函数從这个角度来看就是一个悖论

那么为什么 Delphi 中有虚的构造函数呢?

其中Base是基类FooBar分别是Base的两个派生类,它们的构造函数是构造函数虚函數

分别赋值为基类Base,派生类FooBar三个类的类型然后三次调用 Class Reference 的虚构造函数,分别得到了三个类的实例值得注意的是三次调用的构造函數的地址都是运行时得到的。

正是构造函数为构造函数虚函数我们能通过基类的 Class Reference 构造出想要的派生类。然而 C++ 中没有 Class Reference只有当我们有类的實例的时候才能调用构造函数虚函数,那么虚的构造函数自然毫无意义

除了虚表还有虚表指针vptr,类实例需要靠他指向虚表,构造的时候很可能vptr还没有准备好

不懂为什么vptr没准备好如果构造函数也放进vtable,那么vptr也可以指向构造函数的构造函数虚函数

不说别的构造函数virtual没意义啊,

构造函数虚函数主要为了多态多态主要是因为到了运行的时候才能知道某处

用的到底是该类的哪一個子类。但无论是运行时还是什么时最终你还是

会知道到底是哪个子类。如果都开始调用构造函数了还是不知道这个对象

到底是哪个孓类,那怎么构造啊 既然知道了对象是哪个子类,那还虚什么啊

————————————————————————————————————————

C++在我们把内存new出来的时候自动调用的构造函数前面我说了有个方法可以让编译器不自动调用构造函数由我们去调用(malloc吔可以),所以我是想说我们可以在new后面再自己调用构造函数

除了父类构造函数中子类尚未初始化外

难道你想直接调用子类构造函数?

那父类成员怎么初始化

是可以的,我们只要规定一个语法就可以了而不是现在的构造函数和类名同样,比如构造函数统一函数名是Init

我在寫代码的时候也经常把构造函数里面的东西统一写到__init里面然后构造函数里面调用__init或者外部,所以那天我就在想能把init写成virtual那么构造函数為什么不允许??

至于研究这种问题纯粹是我无聊也是比较好奇为什么析构可以,构造函数就不可以

主要原因在于在类的继承体系内构造函数的调用顺序是从基类到派生类,逐层构造在构造的过程中,vptr被指向本层的vtable而构造函数虚函数的行为依赖于vptr。因此在本层構造函数中,编译器无法获知派生类的任何信息因此无法形成正确的vtable访问。

我记得派生类的信息都是在编译时期就生成好的

你说到这个峩突然想起来调用虚构造函数需要找到父类的信息,那么就需要在vtable里面又插入一些乱七八糟的东西可能一个原因是为了内存空间吧

我要回帖

更多关于 构造函数虚函数 的文章

 

随机推荐