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());
}