有没有办法做一个C++;结构值是否初始化所有POD成员变量? 假设我有一个C++结构,它既有POD成员又有非POD成员变量: struct Struct { std::string String; int Int; };
为了让我的程序产生可复制的行为,我需要在构造时初始化所有成员变量。我可以使用初始值设定项列表:有没有办法做一个C++;结构值是否初始化所有POD成员变量? 假设我有一个C++结构,它既有POD成员又有非POD成员变量: struct Struct { std::string String; int Int; };,c++,constructor,initialization,C++,Constructor,Initialization,为了让我的程序产生可复制的行为,我需要在构造时初始化所有成员变量。我可以使用初始值设定项列表: Struct::Struct() : Int() {} 问题是,只要我需要更改结构并添加新的POD成员变量(比如bool bool),我就有可能忘记将其添加到初始值设定项列表中。然后,在构造结构期间,新成员变量的值将不会初始化 我也不能使用memset()技巧: Struct::Struct() { memset( this, 0, sizeof( *this ) ); //can brea
Struct::Struct() : Int() {}
问题是,只要我需要更改结构并添加新的POD成员变量(比如bool bool
),我就有可能忘记将其添加到初始值设定项列表中。然后,在构造结构期间,新成员变量的值将不会初始化
我也不能使用memset()
技巧:
Struct::Struct()
{
memset( this, 0, sizeof( *this ) ); //can break non-POD member variables
}
因为调用memset()
在这种情况下,有没有一种方法可以强制所有POD成员变量的值初始化,而不显式地添加它们的初始化?链接问题
在这种情况下,有没有一种方法可以强制所有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 ~ $
prasoon@prasoon-桌面~$cat check.cpp&&clang++check.cpp&&a.out
#包括
结构{
std::字符串;
int-int;
布尔克;
//添加添加添加
};
struct指令:struct
{
指令():结构(){}
};
int main()
{
指示我;
std::cout最干净的方法是编写自动初始化的模板类初始化的:
编辑:我现在意识到,通过允许您声明已初始化
,它可以变得更加灵活。这意味着您可以在不修改原始结构
的情况下声明初始化。默认初始化“T()”的灵感来自Prasoons answer
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;
}
模板
结构已初始化
{
公众:
初始化()
{value=T();}
已初始化(T)
{value=t;}
已初始化(常量已初始化&x)
{value=x.value;}
T*运算符&({return&value;}
运算符T&({返回值;}
私人:
T值;
};
结构体
{
std::字符串;
int-int;
};
结构GlorifiedPodStruct
{
std::字符串;
初始化Int;
};
无效测试()
{
荣耀的odstruct s;
s、 Int=1;
intb=s.int;
int*指针=&s.int;
初始化s2;
}
这可以编译,但可能需要更多的转换运算符、对volatile等关键字的处理。但您可以这样做。您可以添加一个基本结构:
struct PODStruct
{
PODStruct(unsinged int count) { memset( this, 0, count);}
};
然后你的结构从这个基本结构派生,如果你有多个基本结构
struct Struct : PODStruct
{
Struct();
std::string Str;
int Int;
}
Struc::Struct() : PODStruct(sizeof(Struct))
{
}
-1你很幸运,得到了零,因为i
所在的内存恰好初始化为零。这不是标准所保证的。@Martin B:我想这是C++03所保证的。请看一下我的问题,我在那里学到了一些东西——我的道歉。我正在删除否决票,添加否决票。嗯。看很好,但是将值设置为私有,然后提供对它的完全访问权的目的不是什么?将其公开并删除转换不是更干净吗?@sharptooth:其思想是,您可以使用初始化的几乎像int
一样。例如,初始化的a;int b=a;
工作。如果对于转换运算符,您需要显式地访问值
成员。@马丁B:是的,关于直接访问,您是对的,我没有想到。仍然使值
私有是没有意义的。@sharptooth:值是私有的或不是真正重要的。只是当初始化时
是完全交换通过T
,您无论如何都不需要访问value
。@Martin B:感谢您的澄清。我建议每个成员都是const
。特别是当它们都是公共的时候,强制不可变是很有意义的。您可以使用数组初始化语法来创建实例:Struct s={code>,0}
@Daniel:我想什么时候把它放在一个容器里?@GMan:在这种情况下,我会把它放在一个std::shared\u ptr
中。或者决定正确地封装成员并移除const
。@Daniel:所有的公众成员都没有什么问题。@Daniel:我不需要你和我一起当心理医生,或者叫我c失意。非常粗鲁。在这种情况下,根据我们掌握的信息,让所有成员都const
不是一个合适的解决方案,因为你已经改变了类可以做的事情。还有其他解决方案可以解决这个问题,但不会改变可用性。虽然这并不能消除你的解决方案可以应用于d的可能性在不同的情况下(我从来没有说过),这确实意味着你的解决方案相对于其他解决方案来说是不够的。这会导致UB。你不能在非POD类型上使用memset
,比如std::string
。