C++ 是C+的成员+;默认情况下是否将结构初始化为0?
我有一个C++ 是C+的成员+;默认情况下是否将结构初始化为0?,c++,C++,我有一个struct: struct Snapshot { double x; int y; }; 我希望x和y为0。默认情况下它们是0还是我必须执行以下操作: Snapshot s = {0,0}; 将结构归零的其他方法有哪些?如果不初始化结构,则这些方法不为空 Snapshot s; // receives no initialization Snapshot s = {}; // value initializes all members 第二个将使所有成员为零,第
struct
:
struct Snapshot
{
double x;
int y;
};
我希望x
和y
为0。默认情况下它们是0还是我必须执行以下操作:
Snapshot s = {0,0};
将结构归零的其他方法有哪些?如果不初始化结构,则这些方法不为空
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
第二个将使所有成员为零,第一个将它们保留为未指定的值。请注意,它是递归的:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
第二个将使p.s.{x,y}
0。如果结构中有构造函数,则不能使用这些聚合初始值设定项列表。如果是这种情况,则必须向这些构造函数添加适当的初始化
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
将x和y都初始化为0。请注意,您可以使用
x(),y()
来初始化它们,而不考虑它们的类型:这就是值初始化,通常会产生一个适当的初始值(0表示int,0.0表示double,为具有用户声明构造函数的用户定义类型调用默认构造函数,…)。这一点很重要,尤其是当结构是模板时 否,默认情况下它们不是0。确保所有值或默认值均为0的最简单方法是定义构造函数
Snapshot() : x(0), y(0) {
}
这将确保快照的所有使用都具有初始化值 我认为正确的答案是它们的值没有定义。通常,在运行调试版本的代码时,它们被初始化为0。运行发布版本时通常不是这种情况。通常不是。但是,在函数/中声明为文件作用域或静态的结构将/初始化为0(与这些作用域的所有其他变量一样): 因为这是一个POD(本质上是一个C结构),所以用C方式初始化它没有什么害处:
Snapshot s;
memset(&s, 0, sizeof (s));
或者类似地
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
在C++程序中,我不想使用<代码> CALROCUR()/<代码>。C++中的< P>,不使用参数构造函数。在C语言中不能有构造函数,因此请使用
memset
或-有趣的解决方案-指定的初始值设定项:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
有了POD,你也可以写作
Snapshot s = {};
不应该在C++中使用MeMSET,MeMSET的缺点是如果结构中有一个非POD,它会破坏它。 或者像这样:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
struct init
{
模板
算子T*()
{
返回新的T();
}
};
快照*s=init();
将pod成员移动到基类以缩短初始值设定项列表:
struct foo_pod
{
int x;
int y;
int z;
};
struct foo : foo_pod
{
std::string name;
foo(std::string name)
: foo_pod()
, name(name)
{
}
};
int main()
{
foo f("bar");
printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}
缺点是结构不再是POD类型,因为它有一个构造函数。这将破坏某些操作,例如将其写入临时文件。@finnw:C++11修复了此问题,尽管结构不是POD,但它是“标准布局”。这确实不是一个安全的假设。您不应该依赖未初始化的任何内容的值。静态存储持续时间对象始终初始化为零-请参阅标准中的引用。这是否是一种好的风格是另一回事;所有零位不一定都是0.0。但是,您可以检查是否有IEEE754 Double,在这种情况下它必须工作。实际上,调试版本恰好在内存中的这些位置已经有
0
。这与初始化不同!这会在我的编译器中产生很多警告。罗杰:尝试在初始值设定项中使用命名结构,我就是这么做的,在VC 2012中我没有收到任何警告:Snapshot s=Snapshot()@Johannes Schaub-litb将快照s={}代码>为非POD成员工作(用于将它们归零)?C++11现在允许您在结构或类的定义中初始化它们,如下所示:结构快照{double x{0};//带大括号int y=0;//或者只是老派风格的“by assignment”,实际上也是初始化};是“快照S= {}”,是标准的一部分吗?我相信这是C,而不是C++。它将无法编译在一些C++编译器中。我在Cygwin或MinGW下遇到编译失败。这将在C或C++20中工作。在旧的C++标准中,只有当你的编译器是亲切的时候,才能工作。@ ListNeasraceSeRealOrth.OWAT?@安迪,大多数令人烦恼的解析都是看起来像普通Ctos的东西——<代码> SOMyType FoE();code>是典型的一种,尽管它可以发生在其他函数定义中(在这种情况下,函数foo
返回SomeType
)。对于necro很抱歉,但是如果其他人发现了这个问题,我想我会回答。使用std::map并在密钥不存在时返回0。注意
struct foo_pod
{
int x;
int y;
int z;
};
struct foo : foo_pod
{
std::string name;
foo(std::string name)
: foo_pod()
, name(name)
{
}
};
int main()
{
foo f("bar");
printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}