在C ++中避免使用默认构造函数进行初始化

时间:2015-04-04 13:52:40

标签: c++ gcc clang

我需要确保构造函数不初始化某些成员变量:

struct A{
    int a, b;
};
struct B: A{
    int c;
    B():c(42){}
}

char data[sizeof(B)];
B *v=reinterpret_cast<B*>(data);
v->a=42;
v->b=42;
new (v) B;

我希望以这样的方式定义A,即展示位置新运算符不会修改v->av->b。我该怎么做?

讨厌的黑客攻击是将v->av->b所需的值存储在线程局部变量中,然后在A::A()中复制它们。但是,如果B的构造函数创建另一个A,那么这将无效,因此我需要一堆它们。有更快的方法吗?

2 个答案:

答案 0 :(得分:1)

您可能无法保证“旧”A不会触及非标准方法(又名“讨厌的黑客”),因为通常编译器可以准备新的,未初始化的{{1它认为合适。

这是我的建议,然而这是非常不安全的,依赖于未定义的行为,只有AA都有标准布局(没有B函数等等,才有机会工作。):

virtual

另一方面,orthodix方法是为char data[sizeof(B)]; // initialize your A object at *data class B_minus_A { int c; } new (v+sizeof(A)) B_minus_A; // (beware the alignment issues!) B *v=reinterpret_cast<B*>(data); 创建一个接受B参数的构造函数,并将其覆盖的A对象传递给它。这可以保证工作,明显的缺点是你需要支付两个副本的成本(从A到B的构造函数的参数堆栈,反之亦然),并且必须允许你修改{{{}的源代码。 1}}。

答案 1 :(得分:0)

我假设您直接使用硬件,或者使用一些非常高性能的代码来进行此操作。

新展示位置会按顺序调用AB的构造函数。既然都没有修改ab,那么您就是安全的。如果构造函数修改了任一变量,则需要更改构造函数。