C++11 C++;11右值问题
我不知道下面的示例输出是如何产生的,有人能告诉我吗?提前谢谢C++11 C++;11右值问题,c++11,C++11,我不知道下面的示例输出是如何产生的,有人能告诉我吗?提前谢谢 #include <iostream> #include <algorithm> class A { public: // Simple constructor that initializes the resource. explicit A(size_t length) : mLength(length), mData(new int[length]) {
#include <iostream>
#include <algorithm>
class A
{
public:
// Simple constructor that initializes the resource.
explicit A(size_t length)
: mLength(length), mData(new int[length])
{
std::cout << "A(size_t). length = "
<< mLength << "." << std::endl;
}
// Destructor.
~A()
{
std::cout << "~A(). length = " << mLength << ".";
if (mData != NULL) {
std::cout << " Deleting resource.";
delete[] mData; // Delete the resource.
}
std::cout << std::endl;
}
// Copy constructor.
A(const A& other)
: mLength(other.mLength), mData(new int[other.mLength])
{
std::cout << "A(const A&). length = "
<< other.mLength << ". Copying resource." << std::endl;
std::copy(other.mData, other.mData + mLength, mData);
}
// Copy assignment operator.
A& operator=(const A& other)
{
std::cout << "operator=(const A&). length = "
<< other.mLength << ". Copying resource." << std::endl;
if (this != &other) {
delete[] mData; // Free the existing resource.
mLength = other.mLength;
mData = new int[mLength];
std::copy(other.mData, other.mData + mLength, mData);
}
return *this;
}
// Move constructor.
A(A&& other) : mData(NULL), mLength(0)
{
std::cout << "A(A&&). length = "
<< other.mLength << ". Moving resource.\n";
// Copy the data pointer and its length from the
// source object.
mData = other.mData;
mLength = other.mLength;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other.mData = NULL;
other.mLength = 0;
}
// Move assignment operator.
A& operator=(A&& other)
{
std::cout << "operator=(A&&). length = "
<< other.mLength << "." << std::endl;
if (this != &other) {
// Free the existing resource.
delete[] mData;
// Copy the data pointer and its length from the
// source object.
mData = other.mData;
mLength = other.mLength;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other.mData = NULL;
other.mLength = 0;
}
return *this;
}
// Retrieves the length of the data resource.
size_t Length() const
{
return mLength;
}
private:
size_t mLength; // The length of the resource.
int* mData; // The resource.
};
#include <vector>
int main()
{
// Create a vector object and add a few elements to it.
std::vector<A> v;
v.push_back(A(25));
v.push_back(A(75));
::std::cout << "----------------------" << std::endl;
// Insert a new element into the second position of the vector.
//v.insert(v.begin() + 1, A(50));
return 0;
}
std::vector
在容量耗尽时调整大小时,必须移动或复制其内部状态。但是,它不知道移动它存储的A
(对push_back
的两个调用)是否安全,因为移动操作没有标记为noexcept
。因为std::vector
不知道它是安全的,所以它在谨慎和复制值方面犯了错误
// Move constructor.
A(A&& other) noexcept : mData(NULL), mLength(0) { /* ... */ }
// Move assignment operator.
A& operator=(A&& other) noexcept { /* ... */ }
通过这些更改,我得到以下输出:
A(尺码)。长度=25
.
A(A&&). length = 25. Moving resource.
~A(). length = 0.
A(size_t). length = 75.
A(A&&). length = 75. Moving resource.
A(A&&). length = 25. Moving resource.
~A(). length = 0.
~A(). length = 0.
----------------------
~A(). length = 25. Deleting resource.
~A(). length = 75. Deleting resource.
您也可以保留足够的容量(
v.reserve(2);
在调用push_-back
)之前,但是如果您的向量
必须调整大小,您将再次开始复制A
。std::vector
必须在容量耗尽时在调整大小的同时移动或复制其内部状态。但是,它不知道移动它存储的A
(对push_back
的两个调用)是否安全,因为移动操作没有标记为noexcept
。因为std::vector
不知道它是安全的,所以它在谨慎和复制值方面犯了错误
// Move constructor.
A(A&& other) noexcept : mData(NULL), mLength(0) { /* ... */ }
// Move assignment operator.
A& operator=(A&& other) noexcept { /* ... */ }
通过这些更改,我得到以下输出:
A(尺码)。长度=25
.
A(A&&). length = 25. Moving resource.
~A(). length = 0.
A(size_t). length = 75.
A(A&&). length = 75. Moving resource.
A(A&&). length = 25. Moving resource.
~A(). length = 0.
~A(). length = 0.
----------------------
~A(). length = 25. Deleting resource.
~A(). length = 75. Deleting resource.
您也可以保留足够的容量(
v.reserve(2);
在调用push_-back
)之前,但是如果您的vector
需要调整大小,您将再次开始复制A
。您知道std::vector
正在动态分配内存,当它扩展它的内存时,它需要复制它已经拥有的所有数据?请告诉我们你不理解的部分和/或你期望什么。按照@Someprogrammerdude所说的,为了让vector
在向量重新分配时使用移动操作而不是复制操作,必须将移动构造函数/赋值运算符标记为noexcept
。请看,您确实知道std::vector
正在动态分配内存,并且当它扩展内存时,它需要复制它已经拥有的所有数据?请告诉我们您不理解的部分和/或您期望的内容。按照@Someprogrammerdude所说的,为了使向量重新分配时使用移动操作而不是复制操作,必须将移动构造函数/赋值运算符标记为noexcept
。明白了!谢谢知道了!谢谢