C++ 中隐式构造的变量

Implicitly constructed variables in c++

本文关键字:变量 C++      更新时间:2023-10-16

我正在掌握 c++,有一个语言功能我特别难以理解。

我习惯于显式声明和初始化变量,但在 c++ 中,我们有时似乎声明并隐式构造一个变量。

例如,在这个片段中,rdev 似乎是隐式构造的(因为它随后用于构造default_random_engine);

random_device rdev;
default_random_engine gen(rdev());

有人可以解释一下这里发生了什么吗?除了简单的声明(例如int myInt;)之外,我如何区分这一点?

有人可以解释一下这里发生了什么吗?

这些是定义,而不仅仅是声明。变量定义创建变量。在第一种情况下,没有初始化器,指示它应该是默认初始化的。

除了简单的声明(例如int myInt;)之外,我如何区分这一点?

这也是一个定义,创建int变量并使其保持未初始化状态。

您可以声明全局变量而不定义它:

extern int myInt;

extern表示它具有外部链接,并在其他地方定义。其他类型的变量不能在不定义的情况下声明它们。

random_device rdev; // creates an instance of random_device on the stack
                    // with default constructor (taking no arguments)
default_random_engine gen(  // creates an instance of default_random_engine
                            // on the stack
    rdev()                  // passing it the result of
                            // invocation of operator '()'
                            // on the instance rdev of random_device
);

以更冗长的形式相同(有些C++11):

auto rdev = random_device {};
auto gen = default_random_engine { rdev.operator()() };

有人可以解释一下这里发生了什么吗?我怎么能区分这个 来自一个简单的声明,例如 int myInt;

它们都是简单的定义。

唯一的区别是类型的属性。 random_device需要构建,所以它是。 int确实如此,但人们哭得太多了,所以事实并非如此。坦率地说,int的行为与其说是你真正想要的,不如说是一种语言缺陷。

归根结底,这是类型的属性,而不是定义的属性。

如C++标准 (8.5.11) 中所述: If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. — end note ]

这正是您的情况:没有显式初始值设定项的变量定义。那么,让我们看看default-initialized是什么意思(8.5.7):

To default-initialize an object of type T means:
  — if T is a (possibly cv-qualified) class type (Clause 9),
    the default constructor for T is called
    (and the initialization is ill-formed if T has no accessible default constructor);
 — if T is an array type, each element is default-initialized;
 — otherwise, no initialization is performed.

这清楚地说明了您的两个示例之间的区别:

  • random_device 是一个类类型,因此隐式调用其默认构造函数(没有参数的构造函数)。
  • int既不是类类型也不是数组类型,因此不执行初始化,并且在显式初始化它(通过为其赋值)之前,它将具有不确定的值。