我正在尝试重载赋值运算符并尝试使用"复制和交换"成语以避免内存泄漏。我已经实现了自己的默认构造函数和复制构造函数。我只需要知道在我的主要时间我说a=b
和赋值运算符被调用,然后在(第2行)的参数部分发生了什么。我只想知道参数部分中发生的操作。
template <class T>
Mystack<T> & Mystack<T>::operator=(Mystack<T> source) // Line 2,
//Passing by value intentionally
选项1 :默认构造函数被调用,默认构造函数中提到的任何代码都在source
上执行。
选项2 :调用默认构造函数并按值复制,并将b的值复制到source
。
选项3 :调用复制构造函数并按值复制,source
获取与b
中相同的值。
如果以上都不是真的,请告诉我参数部分实际发生了什么。
答案 0 :(得分:0)
template <class T>
Mystack<T> & Mystack<T>::operator=(Mystack<T> source)
该赋值运算符通过值获取其参数,这意味着调用者传递了一个新的Mystack<T>
,但是它会被构造。
当您实现自己的复制构造函数而没有移动构造函数时,如果不是就地构造,那么肯定会调用它。
调用时source
不会调用任何内容,直到你返回,并且在完整表达式结束时调用析构函数会破坏参数。
一些例子:
using A = MyStack<T>;
A make_a();
A a, b;
a = b; // Calls the copy-ctor to construct the argument to op=
a = A(); // Directly constructed as the argument
a = make_a(); // Return-value is directly used as the argument
答案 1 :(得分:0)
传递by-value允许创建新对象。创建此对象的方式取决于它初始化的表达式的类型。如果参数是左值,则调用copy-constructor,同样如果它是rvalue,则调用move-constructor。
这两个函数都是由编译器提供给你的,因为你自己不提供这些函数,也没有声明任何会阻止它们创建的特殊成员函数(以及其他条件)。
MyStack<int> a, b;
a = b; // Calls MyStack(MyStack const&)
a = std::move(b); // Calls MyStack(MyStack&&)
取值的目的是拥有一个全新的对象。这可以通过两种方式完成 - 将旧对象复制到新对象或与不再需要的对象交换所有权。
在a = b
行,b
的内容将复制到参数source
。 a = std::move(b)
通过移除其“胆量”并将其提交给b
来与a
交换所有权。 a
现在拥有b
曾经拥有的任何内容,b
的内部结构处于类似于移动对象的状态。
请注意,按值初始化参数为copy-initialization,尽管名称仍然可以使用move-constructor。