赋值运算符和初始化
The assignment operator and initialization
我正在学习C++编程语言,正在阅读关于赋值运算符(=)的章节。在C++中,初始化和赋值是如此相似的操作,以至于我们可以使用相同的表示法。
但我的问题是:当我初始化一个变量时,我是用赋值运算符来做的吗?当我给一个变量赋值时,我是用赋值运算符来做的吗?我认为唯一的区别是初始化和赋值,因为当我们初始化一个变量时,我们用assignmnet运算符给它一个新值,当我们给一个变量赋值时,我们使用赋值运算符用新值替换该变量的旧值。对吗?
你问
当我初始化一个变量时,我是用赋值运算符来做的吗?
以及所述
当我们初始化一个变量时,我们用赋值运算符给它一个新值
但是,不,你不是。符号=
用于复制初始化和赋值,但初始化不使用赋值运算符。变量的初始化实际上使用了构造函数。
在复制初始化中,它使用复制构造函数。
type x = e; // NOT an assignment operator
首先将e
转换为type
,创建一个临时变量,然后type::type(const type&)
通过复制该临时变量来初始化x
。根本不调用type::operator=(const type&)
。
还有直接初始化,不使用=
符号:
type x(e);
type x{e}; // since C++11
otherclass::otherclass() : x(e) {} // initialization of member variable
虽然初始化和赋值都会给变量一个值,但两者并不使用相同的代码
进一步的细节:对于C++11及更高版本,如果有移动构造函数,复制初始化将使用它,因为转换的结果是临时的。此外,在复制初始化中,编译器可以跳过实际调用复制或移动构造函数,它可以将初始值设定项直接转换为变量。但它仍然必须检查复制或移动构造函数是否存在并且可以访问。复制构造函数也可以采用非常量引用。因此,可能使用type::type(type&&)
,或者type::type(const type&&)
(非常罕见),或者使用type::type(type&)
,而不是type::type(const type&)
。我上面描述的是最常见的情况。
你的想法很正确。使用构造函数,您将分配该类型的新对象,该对象有自己的开销。
当您将赋值复制到变量时,您不想创建新对象,因为您已经有了一个对象。您只需要将赋值对象左侧的相应成员变量设置为合适的大小。
例如:
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
此外,还有另一种情况调用复制构造函数,如下所示:
MyClass other2 = MyClass(object);
这里调用了一个特殊的构造函数,它基本上完成了复制赋值操作的相同工作,但使用了一个新对象,而不是现有对象。
- 为什么初始化时没有调用重载赋值运算符?
- 由于没有使用赋值运算符,映射的值是如何初始化的?
- 在未初始化的变量上使用复合赋值运算符(+=, ..)不是C++中的UB?
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- 为什么我可以在不使用赋值运算符的情况下使用列表初始化普通数组
- Clang 无法在赋值运算符/复制构造函数中检测到未初始化的类成员
- 为什么参数可以在对象初始化时通过赋值运算符传递给构造函数?
- 初始化对象后,用隐式转换而不是赋值运算符调用构造函数有什么意义
- 初始化对象后,如何使用赋值运算符覆盖C++中的类对象
- 初始化对象时复制构造函数/赋值运算符混淆
- 模板化赋值运算符模板实例化失败
- 类内成员初始化是否删除赋值运算符
- 从初始化构造函数和赋值运算符创建的对象有什么区别
- C++11:赋值运算符是否阻止一个类型成为POD,从而全局初始化
- 赋值运算符和初始化
- 如何使我的向量类支持直接初始化/赋值
- 没有默认构造函数的初始化赋值
- C++11:类初始化赋值顺序的主体
- 通过显式调用类构造函数与默认初始化+赋值运算符来使用对象
- GCC 4.7.2 对shared_ptr(模板化)赋值运算符的实现是否存在错误?