如何使用默认值定义结构

How to define a Struct with default values?

本文关键字:结构 定义 默认值 何使用      更新时间:2023-10-16

发现这个问题以前从未被问过,真是太惊讶了。事实上,以前也有人问过,但问题与我的非常不同。它们太复杂和荒谬了,而我会保持简单和切中要害。这就是为什么这个问题需要公布的原因。

现在,当我这样做的时候,

struct A {
    int a = -1;
};

我得到以下错误:ANSI C++ forbids in-class initialization of non-const static member a

现在,除了解决方法之外,有人能告诉我用默认值初始化结构成员变量的最佳方法吗?

首先,让我们看看错误:

ANSI C++ forbids in-class initialization of non-const static member a

初始化真正的实例成员(位于结构实例的内存中)是该结构的构造函数的责任。

静态成员虽然在特定类/结构类型的定义中定义,但实际上并不是该特定类型的任何实例的成员。因此,它不受解释在构造函数体中分配哪个值的约束。这是有道理的,我们不需要任何这种类型的实例来很好地初始化静态成员。

通常,人们在构造函数中编写成员初始化,如下所示:

struct SomeType
{
    int i;
    SomeType()
    {
        i = 1;
    }
}

但这实际上不是初始化,而是赋值。当您输入构造函数的主体时,您所做的就是默认初始化成员。在像int这样的基本类型的情况下,"默认初始化"基本上可以归结为"嗯,只需使用我给你的那些字节中的任何值。"

接下来发生的是,你要求我现在通过赋值运算符采用值1。对于这样一个琐碎的类来说,差异是无法察觉的。但是,当你有const成员(在构建它们时,显然不能用新值来覆盖它们),以及更复杂的不能默认初始化的成员(因为它们没有提供一个零参数的可见构造函数)时,你很快就会发现你无法编译代码。

正确的方法是:

struct SomeType
{
    int i;
    SomeType() : i(1)
    {
    }
}

通过这种方式,您可以初始化而不是分配成员。您可以通过逗号分隔来初始化多个成员。需要注意的是,它们是按照结构中的声明顺序初始化的,而不是按照此表达式中的顺序初始化的。

有时您可能会看到用大括号初始化的成员(类似于i{1}而不是i(c))。差异可能是微妙的,大多数时候都是一样的,而标准的当前修订版正试图消除一些皱纹。但这一切都超出了这个问题的范围。

更新:请记住,您正在尝试编写的代码现在是有效的C++代码,并且自批准C++11以来一直有效。该功能被称为"非静态数据成员初始值设定项",我怀疑您使用的是Visual Studio的某个版本,该版本仍然将对该特定功能的支持列为"部分"。可以将其视为我之前描述的成员初始化语法的一种简短形式,它会自动插入您为该特定类型声明的任何构造函数中。

您可以创建一个默认的构造函数

struct A {
    A() : a{-1} {}
    int a;
};