构造函数不能是虚拟的,为什么?不是骗子

发布于 2024-09-25 12:45:09 字数 721 浏览 8 评论 0原文

可能的重复:
为什么我们没有虚拟构造函数?

我知道这一点之前已被问过,但我不明白其他答案中使用的复杂技术词汇。

我在社区上读到构造函数不能是虚拟的原因是

“虚拟”机制适用于逻辑上完整(完全构造)的对象。我们知道我们使用构造函数来逻辑地初始化我们的对象。换句话说,直到构造函数执行完毕之后,对象才被完全构造出来。因此,我们不能有虚拟构造函数。

有一种误解,认为那时虚拟表还不完整,所以我们不能有虚拟构造函数。就在构造函数开始执行之前,正确构造了虚拟表,并将“this”指针传递给构造函数。此外,虚表机制依赖于实现,并且在 C++ 标准中没有地位。因此,用虚拟表概念来争论这个问题是不合逻辑的。

现在,当构造函数完成执行时,任何其他函数都可以是虚拟的。析构函数也不例外,因为它是一个函数。如果我们使用基类指针来引用派生类对象,使用它,然后删除它,则需要虚拟析构函数。如果我们有虚拟析构函数,则使用“删除”,从派生到基类开始调用析构函数链。但是,如果析构函数中没有“虚拟”,则仅调用基类析构函数(而不是派生类)。这(可能)会在程序中产生不一致的情况。

上述理由正确吗?答案没有谈论对象的静态和动态类型。

Possible Duplicate:
Why do we not have a virtual constructor?

I know this has been asked before but I didn't understand the complex technical words used in the other answers.

I read on a community the reason that constructors cannot be virtual is

The ‘virtual’ mechanism works on a logically complete (completely constructed) object. We know that we use constructors to logically initialize our objects. In other words, the object is not completely constructed until the constructor has finished executing. Thus, we can’t have virtual constructors.

There is a misconception that by then virtual table is incomplete so we can’t have virtual constructors. Just before the constructor starts executing the virtual table is properly constructed and the ‘this’ pointer passed to the constructors. Moreover, virtual table mechanism is implementation depended, and finds no place in the C++ standard. And hence, to argue over this issue using the virtual table concept is illogical.

Now, as the constructor finishes executing any other function can be virtual. Destructor is no exception to this rule as it is a function. Virtual destructors are required in case we use a base class pointer to refer to a derived class object, use it, and then delete it. If we have virtual destructor, using ‘delete’, a chain of destructors is called starting from the derived to the base. But, had there been no ‘virtual’ in destructor only the base class destructor is called (and not the derived). This (may) generate inconsistencies in the program.

Is the above reason correct? The answer doesn't talk about the static and dynamic types of objects.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

美男兮 2024-10-02 12:45:09

虚拟构造函数没有意义,也没有必要。唯一一次调用构造函数是在创建对象时。您需要知道对象的类型才能创建它,因此静态类型和动态类型是相同的,要调用的正确构造函数就是该类型的构造函数。

这就是为什么它们没有必要。为什么它们没有意义,因为创建对象时,会调用基类构造函数以及派生类构造函数。如果基类构造函数在派生类中被重写,是否意味着基类构造函数根本没有被调用?

其他语言也有虚拟构造函数,可能是因为这些语言中的构造函数是方法,并且它们仅对非静态方法有虚拟调用。但是那些其他语言(首先想到的是 Java 和 Python)必须引入特殊规则,即构造函数必须/应该将其基类显式构造为来自构造函数的调用。 C++ 只是使用非虚拟构造函数来执行此操作(可能在初始值设定项列表中,如果基类构造函数需要参数),并且没有选项可以使用未初始化的基类子对象进入构造函数的主体。

Virtual constructors don't make sense and aren't necessary. The only time you call a constructor is when creating an object. You need to know the type of an object in order to create it, so the static and dynamic types are the same, and the correct constructor to call is the one for that type.

That's why they aren't necessary. Why they don't make sense, is that when creating an object, base class constructors are called as well as derived class constructors. If the base class constructor was overridden in the derived class, is that supposed to mean that the base class constructor isn't called after all?

Other languages have virtual constructors, perhaps because constructors in those languages are methods, and they only have virtual invocation for non-static methods. But those other languages (Java and Python spring to mind) have to introduce special rules that constructors must/should construct their base class explicitly as a call from the constructor. C++ just does it (perhaps in an initializer list, if the base class constructor requires parameters), using non-virtual constructors, and there is no option to enter the body of the constructor with uninitialized base class sub objects.

離殇 2024-10-02 12:45:09

引用C++ 编程语言

构造一个对象,构造函数
需要对象的确切类型
是创造。因此,一个
构造函数不能是虚的。
此外,构造函数不是
很普通的一个函数。在
特别是,它与记忆相互作用
以平常的方式进行管理程序
成员函数则不然。最后,
你不能有一个指向
构造函数。

值得注意的是,C++ 确实有一个称为“虚拟构造函数”的惯用语。您可以在此处了解更多相关信息。

To quote from The C++ Programming Language:

To construct an object, a constructor
needs the exact type of the object it
is to create. Consequently, a
constructor cannot be virtual.
Furthermore, a constructor is not
quite an ordinary function. In
particular, it interacts with memory
management routines in ways ordinary
member functions don’t. Consequently,
you cannot have a pointer to a
constructor.

It must be interesting to note that C++ do have an idiom called virtual constructor. You can read more about that here.

苍景流年 2024-10-02 12:45:09

是的,原因是在调用虚拟函数之前,您需要有一个指向完整对象的指针/引用。当构造函数被调用时,还没有完整的对象。更重要的是,当您执行 new SomeClass() 时,您甚至还没有指针 - 在 new 语句成功完成时返回指针。

Yes, the reason is you need to have a pointer/reference to a complete object already before you can call a virtual function. When the constructor is being invoked there's no complete object yet. Even more, when you do new SomeClass() you don't even have a pointer yet - the pointer is returned upon the new statement is completed successfully.

新人笑 2024-10-02 12:45:09

virtual 关键字不能应用于构造函数,因为构造函数将原始位转换为活动对象,并且在存在可调用成员函数的活动对象之前,成员函数不可能正常工作。不要将构造函数视为对象上的普通成员函数,而是将它们想象为创建对象的静态成员函数。 - C++ 常见问题解答

The virtual keyword cannot be applied to a constructor since a constructor turns raw bits into a living object, and until there is a living object against which to invoke a member function, the member function cannot possibly work correctly. Instead of thinking of constructors as normal member functions on the object, imagine that they are static member functions that create objects. - C++ FAQs

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文