为什么c++没有虚构造函数?
当前回答
尽管由于对象类型是对象创建的先决条件,所以虚拟构造函数的概念不太适合,但它并没有完全被推翻。
GOF的“工厂方法”设计模式利用了虚拟构造函数的“概念”,这在某些设计情况下很方便。
其他回答
你可以在@stefan的回答中找到一个例子和为什么不允许这样做的技术原因。在我看来,这个问题的合理答案是:
virtual关键字的主要用途是在我们不知道基类指针将指向什么类型的对象时启用多态行为。
但这是一种更原始的方式,对于使用虚拟功能,你需要一个指针。指针需要什么?一个指向的对象!(考虑程序正确执行的情况)
因此,我们基本上需要一个已经存在于内存某处的对象(我们不关心内存是如何分配的,它可能是在编译时或运行时),以便我们的指针能够正确地指向该对象。
现在,想象一下当要指向的类的对象被分配一些内存时的情况——>它的构造函数将在该实例本身被自动调用!
所以我们可以看到,我们实际上不需要担心构造函数是虚的,因为在任何情况下,你希望使用多态行为,我们的构造函数已经执行,使我们的对象准备使用!
与面向对象的语言(如Smalltalk或Python)不同,这些语言的构造函数是表示类的对象的虚拟方法(这意味着您不需要GoF抽象工厂模式,因为您可以传递表示类的对象,而不是自己创建),c++是一种基于类的语言,并且没有表示语言的任何构造的对象。该类在运行时不作为对象存在,因此不能对其调用虚方法。
这符合“不用就不用付钱”的理念,尽管我所见过的每个大型c++项目最终都实现了某种形式的抽象工厂或反射。
你也不应该在构造函数中调用虚函数。参见:http://www.artima.com/cppsource/nevercall.html
另外,我不确定是否真的需要虚拟构造函数。你可以在没有它的情况下实现多态构造:你可以编写一个函数,根据所需的参数构造你的对象。
我们有,只是它不是一个构造函数:-)
struct A {
virtual ~A() {}
virtual A * Clone() { return new A; }
};
struct B : public A {
virtual A * Clone() { return new B; }
};
int main() {
A * a1 = new B;
A * a2 = a1->Clone(); // virtual construction
delete a2;
delete a1;
}
我能想到两个原因:
技术原因
对象只有在构造函数结束后才存在。为了使用虚拟表分派构造函数,必须有一个现有的对象和指向虚拟表的指针,但是如果对象仍然不存在,指向虚拟表的指针怎么可能存在呢?:)
逻辑的原因
当您想要声明某种多态行为时,可以使用virtual关键字。但是构造函数没有任何多态性,c++中的构造函数只是简单地将对象数据放到内存中。由于虚表(以及一般的多态性)都是关于多态行为而不是多态数据的,因此声明虚构造函数没有任何意义。