C++ 结构体的成员默认初始化为 0 吗?

问题描述 投票:0回答:9

我有这个

struct

struct Snapshot
{
    double x; 
    int y;
};

我希望

x
y
为 0。它们默认为 0 还是我必须这样做:

Snapshot s = {0,0};

还有哪些其他方法可以将结构归零?

c++ struct initialization aggregate-initialization
9个回答
312
投票

如果不初始化结构体,它们就不为空。

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}
为零。如果结构中有构造函数,则无法使用这些聚合初始值设定项列表。如果是这种情况,您将必须向这些构造函数添加适当的初始化

struct Snapshot {
    int x;
    double y;
    Snapshot():x(0),y(0) { }
    // other ctors / functions...
};

将把 x 和 y 初始化为 0。请注意,您可以使用

x(), y()
来初始化它们,而不管它们的类型:这就是值初始化,通常会产生一个正确的初始值(0 代表 int,0.0 代表 double,调用默认值)具有用户声明构造函数的用户定义类型的构造函数,...)。这很重要,尤其是当您的结构是模板时。


41
投票

不,默认情况下它们不为 0。确保所有值或默认为 0 的最简单方法是定义一个构造函数

Snapshot() : x(0), y(0) {
}

这确保了快照的所有使用都将具有初始化值。


22
投票

一般来说,没有。但是,在函数中声明为文件作用域或静态的结构将被初始化为 0(就像这些作用域的所有其他变量一样):

int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0

void foo() {
  struct { int a, b; } bar; // undefined
  static struct { int c, d; } quux; // 0, 0
}

14
投票

有了POD你也可以写

Snapshot s = {};

你不应该在C++中使用memset,memset有一个缺点,如果结构中有非POD,它会破坏它。

或者像这样:

struct init
{
  template <typename T>
  operator T * ()
  {
    return new T();
  }
};

Snapshot* s = init();

8
投票

在 C++ 中,使用无参构造函数。在 C 中,你不能有构造函数,所以使用

memset
或 - 有趣的解决方案 - 指定的初始值设定项:

struct Snapshot s = { .x = 0.0, .y = 0.0 };

3
投票

由于这是一个 POD(本质上是一个 C 结构),因此以 C 方式初始化它几乎没有什么坏处:

Snapshot s;
memset(&s, 0, sizeof (s));

或类似

Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));

不过,我不会在 C++ 程序中使用

calloc()


2
投票

我相信正确的答案是它们的值是未定义的。通常,在运行代码的调试版本时它们会被初始化为 0。运行发行版本时通常不会出现这种情况。


1
投票

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

1
投票

我知道这个问题非常老了,但是这个问题在谷歌上为我弹出,我找到了另一种方式,并认为我应该在这里添加它:

Snapshot s {};

我不确定此语法需要什么 C/C++ 语言版本。

© www.soinside.com 2019 - 2024. All rights reserved.