拷贝构造函数与移动构造函数

左值与右值的区别

  1. 左值持久,右值短暂(右值要么是字面值常量,要么是表达式求值过程中创建的临时变量)
  2. 左值是变量,右值不能被赋值

左值引用与右值引用

  1. 右值引用是为了支持移动操作,通过&&来获得右值引用
  2. 左值引用是相对于右值引用的,通过&来获得
int i = 42;
int &r = i;       //正确,r引用i
int &&rr = i;     //错误,不能将一个右值绑定到一个左值(变量)上
int &r2 = i*42;   //错误,不能将一个左值绑定到一个右值上
const int &r3 = i*42; //正确,可以将一个const的引用绑定到一个右值上
int &&rr2 = i*42;    //正确,将rr2绑定到一个乘法结果上
int &&rr2 = 42;    //正确,字面值常量是一个右值

标准库move函数
显示的将一个左值转换为对应的右值引用类型;我们可以销毁一个移后源对象,也可以赋予它新值,但不能使用一个移后源对象的值。

#include <iostream>
#include <utility>
#include <vector>
#include <string>
 
int main()
{
    std::string str = "Hello";
    std::vector<std::string> v;
 
    // uses the push_back(const T&) overload, which means 
    // we'll incur the cost of copying str
    v.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";
 
    // uses the rvalue reference push_back(T&&) overload, 
    // which means no strings will be copied; instead, the contents
    // of str will be moved into the vector.  This is less
    // expensive, but also means str might now be empty.
    v.push_back(std::move(str));
    std::cout << "After move, str is \"" << str << "\"\n";
 
    std::cout << "The contents of the vector are \"" << v[0]
                                         << "\", \"" << v[1] << "\"\n";
}

Possible output:


After copy, str is "Hello"
After move, str is ""
The contents of the vector are "Hello", "Hello"

注意:如果没有自已定义移动构造函数,使用std::move()会默认调用拷贝构造函数。

拷贝构造函数与移动构造函数的区别:

  1. 拷贝构造函数的形参是一个左值引用,而移动构造函数的形参是一个右值引用
  2. 拷贝构造函数完成的是整个对象或变量的拷贝,而移动构造函数是生成一个指针指向源对象或变量的地址,接管源对象的内存,相对于大量数据的拷贝节省时间和内存空间。
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <vector>

class Book
{
public:
	Book()
	{
		this->_bookname = " ";
		std::cout << "call default construct function" << std::endl;
	}
	Book(std::string bookname) :_bookname(bookname)
	{
		std::cout << "call construct function:"<<_bookname << std::endl;
	}
	//拷贝构造函数
	Book(const Book& book)
	{
		this->_bookname = book._bookname;
		std::cout << "call copy construct function:"<<_bookname << std::endl;
	}
	//移动构造函数
	Book(const Book&& book)
	{
		this->_bookname = book._bookname;
		std::cout << "call move construct function:"<<_bookname << std::endl;
	}
	
	bool operator < (const Book& book)const
	{
		if (this->_bookname < book._bookname)
			return true;
		return false;
	}
	~Book()
	{
		std::cout << "call destruct function" << _bookname << std::endl << std::endl;
	}
private:
	std::string _bookname;
};

int main()
{
	//std::set<Book> bookset;

	//std::cout << "test bookset insert:" << std::endl;
	//bookset.insert(Book("Linux"));


	//std::cout << "test bookset emplace:" << std::endl;
	//bookset.emplace("C++");
	//std::cout << std::endl;
	for (auto& it : bookset)
	{
		std::cout << it._bookname << std::endl;
	}

	//std::map<int,Book> bookmap;

	//std::cout << "test bookmap insert:" << std::endl;
	//bookmap.insert(std::make_pair(1,"Mysql"));


	//std::cout << "test bookmap emplace:" << std::endl;
	//bookmap.emplace(std::make_pair(2,"Python"));
	//std::cout << std::endl;

	std::vector<Book> bookvec;
	long long t = clock();
	std::cout << "test bookvec push_back:" << std::endl;
	bookvec.push_back(Book("Go"));
	long long t1 = clock();
	std::cout <<"time:"<< t1 - t << std::endl;

	
	std::cout << "test bookvec emplace:" << std::endl;
	bookvec.emplace_back(Book("Jave"));
	long long t2 = clock();
	std::cout << "time:" << t2 - t1 << std::endl;
	system("pause");

	return 0;
}

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值