为什么c++没有虚构造函数?
当前回答
c++中的虚函数是运行时多态性的一种实现,它们将执行函数覆盖。在c++中,当需要动态行为时,通常使用virtual关键字。只有当对象存在时,它才会工作。而构造函数用于创建对象。构造函数将在对象创建时调用。
因此,如果您将构造函数创建为virtual,根据virtual关键字定义,它应该有现有的对象可以使用,但构造函数用于创建对象,因此这种情况将永远不存在。所以你不应该将构造函数作为虚函数使用。
因此,如果我们试图声明虚拟构造函数编译器抛出一个错误:
构造函数不能声明为虚函数
其他回答
虚函数用于根据指针所指向的对象类型调用函数,而不是指针本身的类型。但是构造函数不会被“调用”。它只在声明对象时调用一次。因此,在c++中构造函数不能被设为虚函数。
听可靠消息。:)
选自Bjarne Stroustrup的c++风格和技术常见问题解答为什么没有虚拟构造函数?
虚拟调用是一种在给定局部条件下完成工作的机制 信息。特别地,“virtual”允许我们调用一个函数 只知道任何接口,而不知道对象的确切类型。来 创建对象时需要完整的信息。特别是,你 需要知道你想要创建的确切类型。因此, “对构造函数的调用”不能是虚的。
FAQ条目继续给出了一种不使用虚拟构造函数实现此目的的方法的代码。
虚函数基本上提供多态行为。也就是说,当您使用的对象的动态类型与引用它的静态(编译时)类型不同时,它提供的行为适合于对象的实际类型,而不是对象的静态类型。
现在尝试将这种行为应用于构造函数。当你构造一个对象时,静态类型总是与实际的对象类型相同,因为:
要构造一个对象,构造函数需要它要创建的对象的确切类型[…]此外[…]]则不能有指向构造函数的指针
Bjarne Stroustup (P424 c++编程语言SE)
If you think logically about how constructors work and what the meaning/usage of a virtual function is in C++ then you will realise that a virtual constructor would be meaningless in C++. Declaring something virtual in C++ means that it can be overridden by a sub-class of the current class, however the constructor is called when the objected is created, at that time you cannot be creating a sub-class of the class, you must be creating the class so there would never be any need to declare a constructor virtual.
另一个原因是,构造函数的名字与其类名相同如果我们将构造函数声明为virtual,那么它应该在它的派生类中以相同的名字重新定义,但两个类的名字不能相同。所以不可能有一个虚拟构造函数。
有一个非常基本的原因:构造函数实际上是静态函数,而在c++中没有静态函数可以是虚函数。
如果你有丰富的c++经验,你就会知道静态函数和成员函数之间的区别。静态函数与CLASS相关联,而不是与对象(实例)相关联,因此它们看不到“this”指针。只有成员函数可以是虚函数,因为虚表——使“虚”工作的函数指针的隐藏表——实际上是每个对象的数据成员。
构造函数的任务是什么?它在名称中——“T”构造函数在分配T对象时初始化它们。这将自动排除它成为成员函数!对象必须先存在,然后才有this指针,从而有虚表。这意味着即使语言将构造函数视为普通函数(它并没有,由于相关原因,我不会深入讨论),它们也必须是静态成员函数。
了解这一点的一个好方法是查看“Factory”模式,特别是工厂函数。它们做你想做的事情,你会注意到,如果类T有一个工厂方法,它是ALWAYS STATIC。这是必须的。
推荐文章
- 为什么这个结合赋值和相等检查的if语句返回true?
- cplusplus.com给出的错误、误解或坏建议是什么?
- 找出质数最快的算法是什么?
- c++枚举类可以有方法吗?
- 格式化IO函数(*printf / *scanf)中的转换说明符%i和%d之间的区别是什么?
- 将析构函数设为私有有什么用?
- main()中的Return语句vs exit()
- 为什么c#不提供c++风格的'friend'关键字?
- 在函数的签名中添加关键字
- 我可以调用重载构造函数从另一个构造函数的同类在c# ?
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- 为什么在标准容器中使用std::auto_ptr<>是错误的?
- 用比较double和0
- 保护可执行文件不受逆向工程的影响?
- 在c++中字符串前面的“L”是什么意思?