c++ 在调用构造函数之前初始化基类的POD成员合法吗?

guicsvcw  于 2022-12-01  发布在  其他
关注(0)|答案(1)|浏览(119)

在下列程式码中:

class Base
{
protected:
  int v;

  Base( void * ) { /* doesn't touch v at any point */ }
};

class Derived: public Base
{
public:
  // Changes Base::v before calling Base::Base
  Derived(): Base( ( (void )( v = 42 ), nullptr ) ) {}
};

Derived::Derived在调用Base::Base之前更改了POD成员变量Base::v。已知Base::Base根本没有接触v。目标是在离开Derived::Derived之后将Base::v初始化为42
虽然这在技术上应该是可行的(当Derived::Derived被调用时,Base::v已经在内存中为它分配了空间,并且Base::Base中的任何代码都不会触及它),但问题是,这合法吗?更具体地说,这是否意味着任何未定义的行为,而编译器通常喜欢优化掉这些行为?
请注意,这个问题纯粹是为语言律师准备的,我不是在问是否有更好的方法来做这件事(在大多数情况下显然是有的),我也不是在试图解决任何具体的问题,而是试图从C标准的Angular 来学习更多关于C的知识。

nbysray5

nbysray51#

不,这是无效的:
class.cdtor/1
对于具有重要建构函式的对象,在建构函式开始执行之前指涉对象的任何非静态成员或基底类别会导致未定义的行为。
另请参见上一段下面的示例:

struct W { int j; };
struct X : public virtual W { };
struct Y {
  int* p;
  X x;
  Y() : p(&x.j) {   // undefined, x is not yet constructed
  }
};

相关问题