gpt4 book ai didi

C++ 原始类型初始化 vs.对象初始化

转载 作者:太空宇宙 更新时间:2023-11-04 12:47:05 25 4
gpt4 key购买 nike

我很好奇 C++ 基本内置类型(例如 int)与类的对象相比是如何初始化的。

经过研究,我了解到 C++ 是一种静态类型语言,这意味着类型检查是在编译时而不是运行时完成的。这意味着,原始类型不是类的对象,并且类型不能更改。

那么下面的对象初始化有什么不同:

class Foo
{
public:
int num;
Foo(int n) : num(n) {}
};

Foo bar(5);
Foo bar2{ 5 };
Foo bar3 = 5;

原始初始化:

int num(5);
int num2{ 5 };
int num3 = 5;

我知道 Foo 的实例调用构造函数来初始化,但是如果它不是对象,原始调用或做什么来初始化?

除了 Foo 是“用户定义的创建实例的蓝图”和 int 是“非对象内置类型”之外,还有什么从根本上区分了 Foo 和 int 类型。

最佳答案

类初始化

对于像 Foo 这样具有用户定义构造函数的类,初始化之间的唯一区别是最后一个(称为复制初始化)等同于

Foo bar3 = Foo(5);

也就是说,初始化器表达式被转换为类类型(通过 构造函数),然后bar3that 初始化。 (在 C++17 之前,这在概念上涉及复制或移动,但编译器通常会避免这种开销。)

注意还有一种语法:

Foo bar4={5};

这被称为copy-list-initialization,但与没有= 的版本的唯一区别是不允许使用explicit 构造函数.

结构初始化

这些形式之间缺乏显着差异无法激发使用它们的动机,因此令人困惑。区别在于容器,广义上解释为包括聚合(简单的 C 类 struct)。它们支持具有不同含义的{} 初始化,即构建包含一些数据的对象,而不是从中计算。所以

std::vector<double> a(10,1),b{10,1};

定义 a 有 10 个值(每个都是 1),定义 b 有两个值 10 和 1。

有人建议使用花括号进行初始化应限制在这个含义上以避免混淆。

原始初始化

最后,我们有您的 int 示例。现在应该清楚所有的初始化都是可互换的(除了 list-initialization 禁止缩小转换),因为计算原始值和填充它之间没有区别。也不可能观察到原始类型变量的初始化(或赋值):它只是将值提供为抽象机器的原子操作。 (编译器知道这一点并尽可能多地省略此类变量以提高效率。)

对象

即使 int 也是一个对象(在 C++ 中这个词的意义,而不是 Java 或 Python 的意义),当你有一个 Foo 时,你有两个对象: Foo 本身和它包含的 int num (与它一起创建和销毁)。因此,您对 Foo 对象的初始化也是两个初始化:外部初始化 内部初始化(始终由 num(n) 成员初始化器).

正是这个额外对象的存在将 Fooint 区分开来,而不必根据内存布局在操作上定义一个类: Foo 通常是不同的,因为它不同于它可能包含的任何对象。

关于C++ 原始类型初始化 vs.对象初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50924233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com