C ++在构造函数中调用最终虚函数

C++ Calling final virtual function in constructor

在构造函数和析构函数中调用虚函数确实不是一个好习惯,应该避免。这是因为虚函数受子类影响,但是在构造或析构阶段子类还没有构造(in constructing)或者已经析构(in destructing)。

但是,如果在构造函数或析构函数中调用虚拟 final 函数会发生什么?我认为应该没有问题,因为它在逻辑上没有错误。

禁止在构造函数和析构函数中调用虚函数,因为访问子类的尚未初始化的变量可能发生在子类中声明的虚函数的重写版本中。

虽然 virtual final 函数不是,但它是最终的,无法访问子类的变量。

但这是我的假设,还有更多的理由认为在构造函数或析构函数中调用虚函数是不合理的。

所以,总而言之,

Is calling virtual final function in constructing/destructing phase is allowed in C++ standard?

在 construction/destruction 期间调用虚函数 定义明确 并且完全合法 除了纯虚函数

Calling virtual function in constructor and destructor is forbidden

不知道(也不关心)谁说是"bad"还是"forbidden"从文体角度,代码维护角度... 维护代码的能力首先取决于熟悉相关语言和工具;不知道虚拟调用在这些阶段做什么 (*) 会导致维护人员的误解,这是通过选择更有经验的维护人员而不是简化编程风格来解决的。

(*) 在技术上不是对象的 "lifetime" 的一部分,这甚至不是一个非常有用的概念,因为对象在它们的构造函数中可用和使用(在它们的生命周期开始之前)在任何重要的程序中(我认为标准应该简单地抑制这个不需要的概念)。

accessing to subclass' variable, not initialized yet, can occur in overridden version of virtual function, which is declared in the subclass.

不能。在构造基础 class 子对象 B 期间(比如通过构造函数 B::B()), 正在构造的对象类型根据定义 B.

overridden version of virtual function, which is declared in the subclass.

否,此时没有现有的子class对象,因此没有覆盖。

While virtual final function is not, it's final and there's no way to access to subclass' variables.

没有区别。

多态对象的动态类型由构造函数建立,在基础 classes 的构造函数之后和构造成员之前。

If so, is it widely implemented to most C++ compilers?

实际上,所有编译器都通过更改一个或多个 vtable 指针以指向适合该类型的 vtable 来设置对象的动态类型;这是作为施工的一部分完成的。

意思是在构造过程中,vptr值随着派生对象的构造而改变。

首先,规则是:“不要直接或间接从试图调用正在构造或销毁的对象的构造函数或析构函数中调用虚函数。”那不是意见。这就是 SEI CERT 编码标准。原始文档位于:

https://resources.sei.cmu.edu/downloads/secure-coding/assets/sei-cert-cpp-coding-standard-2016-v01.pdf

和 link 相关规则 OOP50-CPP 位于:

https://wiki.sei.cmu.edu/confluence/display/cplusplus/OOP50-CPP.+Do+not+invoke+virtual+functions+from+constructors+or+destructors.

在回答最初的问题时,这条规则有几个例外。其中之一,OOP50-CPP-EX2,如果函数或 class 被标记为最终的。然后它不能被派生的 class 覆盖。您还可以显式限定函数调用。

是的,final 被广泛实施。