现在的位置: 首页 > 综合 > 正文

C++11 转移语义

2018年04月13日 ⁄ 综合 ⁄ 共 1492字 ⁄ 字号 评论关闭

2.转移语义的定义

右值引用是用来支持转移语义的。转移语义可以将资源 ( 堆,系统对象等 ) 从一个对象转移到另一个对象,这样能够减少不必要的临时对象的创建、拷贝以及销毁,能够大幅度提高 C++ 应用程序的性能。临时对象的维护 ( 创建和销毁 ) 对性能有严重影响。转移语义是和拷贝语义相对的,可以类比文件的剪切与拷贝,当我们将文件从一个目录拷贝到另一个目录时,速度比剪切慢很多。在现有的 C++ 机制中,我们可以定义拷贝构造函数和赋值函数。要实现转移语义,需要定义转移构造函数,还可以定义转移赋值操作符。对于右值的拷贝和赋值会调用转移构造函数和转移赋值操作符。如果转移构造函数和转移拷贝操作符没有定义,那么就遵循现有的机制,拷贝构造函数和赋值操作符会被调用。

增加了转移构造函数和转移复制操作符后,我们的程序运行结果为 :

Move Assignment is called! source: Hello

Move Constructor is called! source: World
代码如下:

#include <iostream>
#include <vector>
using namespace std;
class MyString { 
private: 
	char* _data; 
	size_t   _len; 
	void _init_data(const char *s) { 
		_data = new char[_len+1]; 
		memcpy(_data, s, _len); 
		_data[_len] = '\0'; 
	} 
public: 
	MyString() { 
		_data = NULL; 
		_len = 0; 
	} 

	MyString(const char* p) { 
		_len = strlen (p); 
		_init_data(p); 
	} 

	MyString(const MyString& str) { 
		_len = str._len; 
		_init_data(str._data); 
		std::cout << "Copy Constructor is called! source: " << str._data << std::endl; 
	}     //转移构造函数
	MyString(MyString&& str) { 
		std::cout << "Move Constructor is called! source: " << str._data << std::endl; 
		_len = str._len; 
		_data = str._data; 
		str._len = 0; 
		str._data = NULL; 
	}
       //转移赋值操作符
	MyString& operator=(MyString&& str) { 
		std::cout << "Move Assignment is called! source: " << str._data << std::endl; 
		if (this != &str) { 
			_len = str._len; 
			_data = str._data; 
			str._len = 0; 
			str._data = NULL; 
		} 
		return *this; 
	} 
       

	MyString& operator=(const MyString& str) { 
		if (this != &str) { 
			_len = str._len; 
			_init_data(str._data); 
		} 
		std::cout << "Copy Assignment is called! source: " << str._data << std::endl; 
		return *this; 
	} 

	virtual ~MyString() { 
		if (_data) free(_data); 
	} 
};
int main() 
{ 
	MyString a; 
	a = MyString("Hello"); 
	vector<MyString>vec; 
	vec.push_back(MyString("World"));
	return 0;



抱歉!评论已关闭.