赋值运算符和初始化

Pie*_*lli 2 c++ assignment-operator

我正在研究C ++编程语言,正在阅读有关赋值运算符(=)的章节。在C ++中,初始化和赋值操作非常相似,因此我们可以使用相同的符号。

但是我的问题是:当我初始化变量时,我是否正在使用赋值运算符进行操作?当我分配一个变量时,我是否使用赋值运算符来完成它?我认为唯一的区别是初始化和赋值之间的区别,因为当我们初始化一个变量时,我们使用assignmnet运算符为其赋予了一个新值,当我们将其赋给一个变量时,便使用了新值来替换该变量的旧值。赋值运算符。这样对吗 ?

Ben*_*igt 6

您问

当我初始化变量时,我是用赋值运算符来做的吗?

并且说

当我们初始化变量时,我们使用赋值运算符为其赋予新值

但是,不,你不是。该符号=用于复制初始化和赋值,但是初始化不使用赋值运算符。变量的初始化实际上使用构造函数。

在复制初始化中,它使用复制构造函数。

type x = e; // NOT an assignment operator
Run Code Online (Sandbox Code Playgroud)

首先e将其转换为type,创建一个临时变量,然后通过复制该临时变量进行type::type(const type&)初始化xtype::operator=(const type&)根本没有被调用。

还有直接初始化,它不使用=符号:

type x(e);
type x{e}; // since C++11
otherclass::otherclass() : x(e) {} // initialization of member variable
Run Code Online (Sandbox Code Playgroud)

虽然初始化和赋值都为变量提供了一个值,但是两者并不使用相同的代码来完成该操作。


更多详细信息:在C ++ 11和更高版本中,如果有移动构造函数,则复制初始化将改用它,因为转换结果是临时的。同样,在复制初始化中,允许编译器跳过实际调用复制或移动构造函数的过程,它可以将初始化程序直接转换为变量。但是它仍然必须检查副本或移动构造函数是否存在并且可访问。复制构造函数也可以采用非常量引用。因此,可能type::type(type&&)是使用了或type::type(const type&&)(非常不常见)或type::type(type&)使用了而不是type::type(const type&)。我上面描述的是最常见的情况。


Jac*_*ack 0

你的想法非常正确。使用构造函数,您可以分配该类型的新对象,该对象有其自身的开销。

相反,当您将分配复制给变量时,您不想创建一个新对象,因为您已经有了一个对象。您只需将赋值对象左侧的相应成员变量设置为正确的大小即可。

例如:

MyClass object = MyClass(10); // here the constructor is called
MyClass other = MyClass(5); // here another constructor is called
object = other // here the copy assignment operator is called, you don't need to build any new object, just setting fields
Run Code Online (Sandbox Code Playgroud)

此外,还有另一种情况会调用复制构造函数,如下所示:

MyClass other2 = MyClass(object);
Run Code Online (Sandbox Code Playgroud)

这里调用一个特殊的构造函数,它基本上完成与复制赋值操作相同的工作,但使用一个新对象,而不是现有对象。

  • 在我看来,您应该更清楚地区分“复制构造函数”和“复制赋值”,以及“=”的使用并不总是转换为赋值操作这一事实。 (2认同)