这个成语是什么,什么时候应该使用?它解决了哪些问题?当使用C++ 11时,成语是否会改变?
虽然在许多地方已经提到过,但我们没有任何单一的"它是什么"问题和答案,所以在这里.以下是前面提到的地方的部分列表:
c++ c++-faq copy-constructor assignment-operator copy-and-swap
这是一个初学者的问题,但我很长一段时间没有做过C++,所以这里......
我有一个包含动态分配数组的类,比方说
class A
{
int* myArray;
A()
{
myArray = 0;
}
A(int size)
{
myArray = new int[size];
}
~A()
{
// Note that as per MikeB's helpful style critique, no need to check against 0.
delete [] myArray;
}
}
Run Code Online (Sandbox Code Playgroud)
但现在我想创建一个动态分配的这些类的数组.这是我目前的代码:
A* arrayOfAs = new A[5];
for (int i = 0; i < 5; ++i)
{
arrayOfAs[i] = A(3);
}
Run Code Online (Sandbox Code Playgroud)
但这种情况非常糟糕.因为在循环迭代完成时,A(通过A(3)调用)创建的新对象会被破坏for,这意味着myArray该A实例的内部delete []变为-ed.
所以我认为我的语法必定是非常错误的?我想有一些看起来像矫枉过正的修复,我希望避免:
A …MSDN文章如何:编写移动构造函数具有以下建议.
如果为类提供移动构造函数和移动赋值运算符,则可以通过编写移动构造函数来调用移动赋值运算符来消除冗余代码.以下示例显示了调用移动赋值运算符的移动构造函数的修订版本:
// Move constructor.
MemoryBlock(MemoryBlock&& other)
: _data(NULL)
, _length(0)
{
*this = std::move(other);
}
Run Code Online (Sandbox Code Playgroud)
这个代码是通过双重初始化MemoryBlock的值来实现低效的,还是编译器能够优化掉额外的初始化?我是否应该通过调用移动赋值运算符来编写移动构造函数?
作为此问题的扩展,我正在尝试正确设置我的移动分配。
我有以下代码:
// copy assignment operator
LinkedList<T>& operator= (LinkedList<T> other) noexcept
{
swap(*this, other);
return *this;
}
// move assignment operator
LinkedList<T>& operator= (LinkedList<T>&& other) noexcept
{
swap(*this, other);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用它时,我的代码无法编译。
首先一些代码:
LinkedList<int> generateLinkedList()
{
LinkedList<int> List;
List.add(123);
return List;
}
int main()
{
LinkedList<int> L;
L = generateLinkedList();
^ get an error here...
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
main.cpp(24):错误C2593:'operator ='不明确
linkedlist.h(79):注意:可以是'LinkedList&LinkedList :: operator =(LinkedList &&)noexcept'(指向移动分配运算符)
linkedlist.h(63):注意:或'LinkedList&LinkedList :: operator =(LinkedList)noexcept'(指向副本分配运算符)
main.cpp(24):注意:在尝试匹配参数列表'(LinkedList,LinkedList)'时
我的移动分配运算符是错误的,还是使用错误的方式?