【发布时间】:2016-01-05 09:07:34
【问题描述】:
我是否可以在 C++98 中使用复制构造函数和赋值运算符来模拟移动构造函数和移动赋值运算符功能,以提高性能,只要我知道复制构造函数和复制赋值将只为代码中的临时对象调用或者我正在插入针在我眼里?
我举了两个例子,一个是普通的复制构造函数和复制赋值运算符,另一个是模拟移动构造函数和移动赋值运算符并在向量中推送 10000 个元素来调用复制构造函数。
普通拷贝构造函数和拷贝赋值运算符的例子(copy.cpp)
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class MemoryBlock
{
public:
// Simple constructor that initializes the resource.
explicit MemoryBlock(int length)
: _length(length)
, _data(new int[length])
{
}
// Destructor.
~MemoryBlock()
{
if (_data != NULL)
{
// Delete the resource.
delete[] _data;
}
}
//copy constructor.
MemoryBlock(const MemoryBlock& other): _length(other._length)
, _data(new int[other._length])
{
std::copy(other._data, other._data + _length, _data);
}
// copy assignment operator.
MemoryBlock& operator=(MemoryBlock& other)
{
//implementation of copy assignment
}
private:
int _length; // The length of the resource.
int* _data; // The resource.
};
int main()
{
// Create a vector object and add a few elements to it.
vector<MemoryBlock> v;
for(int i=0; i<10000;i++)
v.push_back(MemoryBlock(i));
// Insert a new element into the second position of the vector.
}
使用复制构造函数和复制赋值运算符模拟移动构造函数和移动赋值运算符功能的示例(move.cpp)
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class MemoryBlock
{
public:
// Simple constructor that initializes the resource.
explicit MemoryBlock(int length=0)
: _length(length)
, _data(new int[length])
{
}
// Destructor.
~MemoryBlock()
{
if (_data != NULL)
{
// Delete the resource.
delete[] _data;
}
}
// Move constructor.
MemoryBlock(const MemoryBlock& other)
{
// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
(const_cast<MemoryBlock&>(other))._data = NULL;
//other._data=NULL;
}
// Move assignment operator.
MemoryBlock& operator=(const MemoryBlock& other)
{
//Implementation of move constructor
return *this;
}
private:
int _length; // The length of the resource.
int* _data; // The resource.
};
int main()
{
// Create a vector object and add a few elements to it.
vector<MemoryBlock> v;
for(int i=0; i<10000;i++)
v.push_back(MemoryBlock(i));
// Insert a new element into the second position of the vector.
}
我观察到性能有所提高,但需要付出一些代价:
$ g++ copy.cpp -o copy
$ time ./copy
real 0m0.155s
user 0m0.069s
sys 0m0.085s
$ g++ move.cpp -o move
$ time ./move
real 0m0.023s
user 0m0.013s
sys 0m0.009s
我们可以观察到性能的提高需要一些成本。
- 实现移动构造函数和移动赋值有任何缺陷 运算符在 c++98 中模拟功能,即使我确信复制 构造函数和赋值仅在临时对象存在时调用 创建?
- 有没有其他方法/技术来实现移动构造函数 和 c++98 中的赋值运算符?
【问题讨论】:
-
[OT]:删除空指针是noop,所以不需要检查。
-
@Jarod42,是的,我错过了长度分配。
-
你的 const-cast 是未定义的行为。您的“移动构造函数”不知道它是否已收到内存块的实际 const 实例。
std::auto_ptr有一些类似于移动语义的东西,这涉及到处理一个构造函数,该构造函数对对象进行非常量引用。 -
@AndreKostur 作业可能有未定义的行为。 (这绝对是糟糕的风格和不安全的代码。)演员表本身没有。
标签: c++ vector constructor copy-constructor c++98