高赞回答说的很不错但是不够詳细,我来补充一些
TLDR:构造函数可以是构造函数虚函数,例如 Delphi 就有这样的设计但是C++中构造函数不能是构造函数虚函数。
从C++的视角来看我们只能在编译时明确我们要构造的类的类型,才可以拿到这个类的构造函数再使用这个构造函数构造我们想要的类,虚的构造函数從这个角度来看就是一个悖论
那么为什么 Delphi 中有虚的构造函数呢?
其中Base
是基类Foo
和Bar
分别是Base
的两个派生类,它们的构造函数是构造函数虚函數
分别赋值为基类Base
,派生类Foo
和Bar
三个类的类型然后三次调用 Class Reference 的虚构造函数,分别得到了三个类的实例值得注意的是三次调用的构造函數的地址都是运行时得到的。
正是构造函数为构造函数虚函数我们能通过基类的 Class Reference 构造出想要的派生类。然而 C++ 中没有 Class Reference只有当我们有类的實例的时候才能调用构造函数虚函数,那么虚的构造函数自然毫无意义
不懂为什么vptr没准备好如果构造函数也放进vtable,那么vptr也可以指向构造函数的构造函数虚函数
不说别的构造函数virtual没意义啊,
构造函数虚函数主要为了多态多态主要是因为到了运行的时候才能知道某处
用的到底是该类的哪一個子类。但无论是运行时还是什么时最终你还是
会知道到底是哪个子类。如果都开始调用构造函数了还是不知道这个对象
到底是哪个孓类,那怎么构造啊 既然知道了对象是哪个子类,那还虚什么啊
————————————————————————————————————————
C++在我们把内存new出来的时候自动调用的构造函数前面我说了有个方法可以让编译器不自动调用构造函数由我们去调用(malloc吔可以),所以我是想说我们可以在new后面再自己调用构造函数
除了父类构造函数中子类尚未初始化外
难道你想直接调用子类构造函数?
那父类成员怎么初始化
是可以的,我们只要规定一个语法就可以了而不是现在的构造函数和类名同样,比如构造函数统一函数名是Init
我在寫代码的时候也经常把构造函数里面的东西统一写到__init里面然后构造函数里面调用__init或者外部,所以那天我就在想能把init写成virtual那么构造函数為什么不允许??
至于研究这种问题纯粹是我无聊也是比较好奇为什么析构可以,构造函数就不可以
主要原因在于在类的继承体系内构造函数的调用顺序是从基类到派生类,逐层构造在构造的过程中,vptr被指向本层的vtable而构造函数虚函数的行为依赖于vptr。因此在本层構造函数中,编译器无法获知派生类的任何信息因此无法形成正确的vtable访问。
我记得派生类的信息都是在编译时期就生成好的
你说到这个峩突然想起来调用虚构造函数需要找到父类的信息,那么就需要在vtable里面又插入一些乱七八糟的东西可能一个原因是为了内存空间吧