假设我有一个包含POD和非POD成员变量的C ++结构:
struct Struct {
std::string String;
int Int;
};
并且为了让我的程序产生可重现的行为,我希望在构造时初始化所有成员变量。我可以使用初始化列表:
Struct::Struct() : Int() {}
问题是我需要更改我的结构并添加一个新的POD成员变量(比如bool Bool
)我冒险忘记将其添加到初始化列表中。然后在结构构造期间不会对新成员变量进行值初始化。
此外,我无法使用memset()
技巧:
Struct::Struct()
{
memset( this, 0, sizeof( *this ) ); //can break non-POD member variables
}
因为调用memset()
来覆盖已构造的非POD成员变量可能会破坏这些变量。
有没有办法在没有明确添加初始化的情况下强制执行所有POD成员变量的值初始化?
答案 0 :(得分:10)
关联问题here
有没有办法在没有明确添加初始化的情况下强制执行所有POD成员变量的值初始化?
我不确定[直接]是否可以这样做,但以下工作
prasoon@prasoon-desktop ~ $ cat check.cpp && clang++ check.cpp && ./a.out
#include <iostream>
struct Struct {
std::string String;
int Int;
bool k;
// add add add
};
struct InStruct:Struct
{
InStruct():Struct(){}
};
int main()
{
InStruct i;
std::cout<< i.k << " " << i.Int << std::endl;
}
0 0
prasoon@prasoon-desktop ~ $
答案 1 :(得分:10)
最干净的方法是编写自动初始化的模板类initialized<T>
:
initialized<Struct>
,可以使其变得更加灵活。这意味着您可以在不修改原始Struct
的情况下声明初始化。默认初始化'T()'的灵感来自Prasoons的回答。
template<class T>
struct initialized
{
public:
initialized()
{ value = T(); }
initialized(T t)
{ value = t; }
initialized(const initialized<T>& x)
{ value = x.value; }
T* operator &() { return &value; }
operator T&() { return value; }
private:
T value;
};
struct PodStruct
{
std::string String;
int Int;
};
struct GlorifiedPodStruct
{
std::string String;
initialized<int> Int;
};
void Test()
{
GlorifiedPodStruct s;
s.Int = 1;
int b = s.Int;
int * pointer = &s.Int;
initialized<PodStruct> s2;
}
这可以编译,但可能需要更多转换运算符,处理volatile等关键字。但是你明白了。
答案 2 :(得分:-1)
您可以添加基础结构:
struct PODStruct
{
PODStruct(unsinged int count) { memset( this, 0, count);}
};
然后你的结构派生自这个基础结构,如果你有多个基本结构,首先放置
struct Struct : PODStruct
{
Struct();
std::string Str;
int Int;
}
Struc::Struct() : PODStruct(sizeof(Struct))
{
}