为什么c++没有虚构造函数?


当前回答

面试答案是:virtual ptr和table是和对象相关的,而不是和类相关的。因此构造函数构建虚表 因此,我们不能有虚构造函数,因为在创建obj之前没有虚表。

其他回答

听可靠消息。:)

选自Bjarne Stroustrup的c++风格和技术常见问题解答为什么没有虚拟构造函数?

虚拟调用是一种在给定局部条件下完成工作的机制 信息。特别地,“virtual”允许我们调用一个函数 只知道任何接口,而不知道对象的确切类型。来 创建对象时需要完整的信息。特别是,你 需要知道你想要创建的确切类型。因此, “对构造函数的调用”不能是虚的。

FAQ条目继续给出了一种不使用虚拟构造函数实现此目的的方法的代码。

我能想到两个原因:

技术原因

对象只有在构造函数结束后才存在。为了使用虚拟表分派构造函数,必须有一个现有的对象和指向虚拟表的指针,但是如果对象仍然不存在,指向虚拟表的指针怎么可能存在呢?:)

逻辑的原因

当您想要声明某种多态行为时,可以使用virtual关键字。但是构造函数没有任何多态性,c++中的构造函数只是简单地将对象数据放到内存中。由于虚表(以及一般的多态性)都是关于多态行为而不是多态数据的,因此声明虚构造函数没有任何意义。

你可以在@stefan的回答中找到一个例子和为什么不允许这样做的技术原因。在我看来,这个问题的合理答案是:

virtual关键字的主要用途是在我们不知道基类指针将指向什么类型的对象时启用多态行为。

但这是一种更原始的方式,对于使用虚拟功能,你需要一个指针。指针需要什么?一个指向的对象!(考虑程序正确执行的情况)

因此,我们基本上需要一个已经存在于内存某处的对象(我们不关心内存是如何分配的,它可能是在编译时或运行时),以便我们的指针能够正确地指向该对象。

现在,想象一下当要指向的类的对象被分配一些内存时的情况——>它的构造函数将在该实例本身被自动调用!

所以我们可以看到,我们实际上不需要担心构造函数是虚的,因为在任何情况下,你希望使用多态行为,我们的构造函数已经执行,使我们的对象准备使用!

c++的虚拟构造函数是不可能的。例如,不能将构造函数标记为虚函数。试试这段代码

#include<iostream.h>
using namespace std;
class aClass
{
    public:
        virtual aClass()
        {   
        }  
};
int main()
{
    aClass a; 
}

它会导致错误。这段代码试图将构造函数声明为虚函数。 现在让我们试着理解为什么要使用virtual关键字。Virtual关键字用于提供运行时多态性。例如,试试这段代码。

#include<iostream.h>
using namespace std;
class aClass
{
    public:
        aClass()
        {
            cout<<"aClass contructor\n";
        }
        ~aClass()
        {
            cout<<"aClass destructor\n";
        }

};
class anotherClass:public aClass
{

    public:
        anotherClass()
        {
            cout<<"anotherClass Constructor\n";
        }
        ~anotherClass()
        {
            cout<<"anotherClass destructor\n";
        }

};
int main()
{
    aClass* a;
    a=new anotherClass;
    delete a;   
    getchar(); 
}

In main a=new anotherClass; allocates a memory for anotherClass in a pointer a declared as type of aClass.This causes both the constructor (In aClass and anotherClass) to call automatically.So we do not need to mark constructor as virtual.Because when an object is created it must follow the chain of creation (i.e first the base and then the derived classes). But when we try to delete a delete a; it causes to call only the base destructor.So we have to handle the destructor using virtual keyword. So virtual constructor is not possible but virtual destructor is.Thanks

有一个非常基本的原因:构造函数实际上是静态函数,而在c++中没有静态函数可以是虚函数。

如果你有丰富的c++经验,你就会知道静态函数和成员函数之间的区别。静态函数与CLASS相关联,而不是与对象(实例)相关联,因此它们看不到“this”指针。只有成员函数可以是虚函数,因为虚表——使“虚”工作的函数指针的隐藏表——实际上是每个对象的数据成员。

构造函数的任务是什么?它在名称中——“T”构造函数在分配T对象时初始化它们。这将自动排除它成为成员函数!对象必须先存在,然后才有this指针,从而有虚表。这意味着即使语言将构造函数视为普通函数(它并没有,由于相关原因,我不会深入讨论),它们也必须是静态成员函数。

了解这一点的一个好方法是查看“Factory”模式,特别是工厂函数。它们做你想做的事情,你会注意到,如果类T有一个工厂方法,它是ALWAYS STATIC。这是必须的。