【发布时间】:2013-08-07 18:24:21
【问题描述】:
我一直在测试一些 C++11 的一些特性。 我遇到了右值引用和移动构造函数。
我实现了我的第一个移动构造函数,这里是:
#include <iostream>
#include <vector>
using namespace std;
class TestClass{
public:
TestClass(int s):
size(s), arr(new int[s]){
}
~TestClass(){
if (arr)
delete arr;
}
// copy constructor
TestClass(const TestClass& other):
size(other.size), arr(new int[other.size]){
std::copy(other.arr, other.arr + other.size, arr);
}
// move constructor
TestClass(TestClass&& other){
arr=other.arr;
size=other.size;
other.arr=nullptr;
other.size=0;
}
private:
int size;
int * arr;
};
int main(){
vector<TestClass> vec;
clock_t start=clock();
for(int i=0;i<500000;i++){
vec.push_back(TestClass(1000));
}
clock_t stop=clock();
cout<<stop-start<<endl;
return 0;
}
代码运行良好。无论如何在复制构造函数中放置一个 std::cout 我注意到它被调用了!而且很多次..(移动构造函数 500000 次,复制构造函数 524287 次)。
更让我吃惊的是,如果我将代码中的复制构造函数注释掉,整个程序会快很多,而这一次移动构造函数被调用了 1024287 次。
有什么线索吗?
【问题讨论】:
-
你使用的是哪个编译器?
-
@pinoscotto 附带说明:你有未定义的行为,你应该使用
delete[],并且你不需要在析构函数中使用if (arr) ...。所以析构函数应该是简单的~TestClass(){ delete[] arr; }。 -
@pinoscotto 在没有 if 的情况下调用
delete[]总是安全的:(1)如果new在初始化中抛出,析构函数将不会被调用(2)否则你要么点到有效地址 (3) 或拥有nullptr,删除nullptr始终是安全的(由标准保证)。
标签: c++ c++11 rvalue-reference move-constructor