为什么不能在结构体内初始化成员变量?

59

为什么我们不能在结构体内初始化成员变量?

例子:

struct s {
   int i = 10;
};

3
因为那是定义而不是声明。 - Archmede
6个回答

40

如果你想在 struct声明中初始化非静态成员:

在C++(不是C)中,structs几乎等同于类,可以在构造函数中初始化成员。

struct s {
    int i;

    s(): i(10)
    {
    }
};
如果您想初始化一个实例:
在C或C++中:
struct s {
    int i;
};

...

struct s s_instance = { 10 };

C99 还具有称为指定初始化器的功能:

struct s {
    int i;
};

...

struct s s_instance = {
    .i = 10,
};

还有一个GNU C扩展,它非常类似于C99指定初始化程序,但最好使用更具可移植性的东西:

struct s s_instance = {
    i: 10,
};

37
直接的答案是因为结构定义声明了一种类型,而不是可以初始化的变量。你的例子是:
struct s { int i=10; };

这并不是声明任何变量 - 它定义了一种类型。要声明一个变量,你需要在 }; 之间添加一个名称,然后在之后初始化它:

struct s { int i; } t = { 10 };

正如Checkers所指出的,在C99中,您还可以使用指定初始化程序(这是一项很棒的改进——有一天,C语言将赶上Fortran 66用于数据初始化的其他功能,主要是可指定次数的重复初始化)。 对于这个简单的结构,没有任何好处。 如果您有一个具有20个成员的结构体,并且只需要初始化其中一个(例如因为您有一个标志,指示其余结构是否已初始化),则更有用:
struct s { int i; } t = { .i = 10 };

这种符号也可以用于初始化union,选择初始化union的哪个元素。

22

请注意,在C++11中,以下声明现在是被允许的:

struct s {
   int i = 10;
};

这是一个老问题,但它在谷歌中排名很高,可能需要澄清。


它到底是做什么的?这是否与默认构造函数的初始化值相似?如果是,那么在调用复制或移动构造函数时,这个赋值也会执行吗? - starturtle
如果成员没有被显式初始化,它基本上会被插入到构造函数的成员初始化列表中。 - Trass3r
这个有文档记录吗? - Andrew Truckle

8

编辑2:此答案是在2008年编写的,与C++98相关。成员初始化规则在语言的后续版本中已更改。

编辑:该问题最初被标记为c++,但发布者说它涉及c,因此我重新标记了该问题,但仍然保留答案...

在C ++中,struct只是一个默认为public而不是private的成员和继承的class

C ++仅允许初始化static const整数成员,其他成员必须在构造函数中初始化,或者如果structPOD,则在初始化列表中(在声明变量时)进行初始化。

struct bad {
    static int answer = 42; // Error! not const
    const char* question = "what is life?"; // Error! not const or integral
};

struct good {
    static const int answer = 42; // OK
    const char* question;
    good() 
        : question("what is life?") // initialization list
        { }
};

struct pod { // plain old data
    int answer;
    const char* question;
};
pod p = { 42, "what is life?" };

1
这已经过时了...现在C++可以做到! - sergiol

2

我们无法初始化,因为当我们声明任何结构时,实际上我们只是告诉编译器它们的存在,即没有为其分配内存,如果我们使用没有为其分配内存的成员进行初始化。通常情况下,当我们初始化任何变量时,这取决于我们声明变量的位置,编译器会为该变量分配内存。

int a = 10;
  • 如果它是自动的,那么将在堆栈内存中分配。
  • 如果它是全局的,那么将在数据区段内存中分配。

因此,在结构体的情况下,需要哪种内存来保存数据,但没有内存可用,因此无法初始化它。


2
虽然你的回答看起来不错,但你应该尝试让它更清晰,例如纠正措辞! - gsamaras

0

就像你说的,它只是一个成员而不是变量。当你声明一个变量时,编译器也会为这些变量提供内存空间,你可以在其中放置值。在结构体成员的情况下,编译器不会为其提供内存空间,因此除非你创建一个该结构类型的变量,否则无法为结构体成员分配值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接