移动语义大大降低了对象转移的成本,通常右值转左值会触发移动语义,左值转左值触发复制语义
可以看看下面的输出是什么
#include <iostream> #include <string> #include <vector> class CDemo { public: CDemo() { //std::cout << "构造函数" << std::endl; }; CDemo(CDemo&& cur) noexcept { std::cout << "移动函数" << std::endl; }; CDemo(CDemo& cur) { std::cout << "拷贝函数" << std::endl; }; CDemo& operator=(const CDemo& cur) { std::cout << "赋值函数" << std::endl; return *this; } ~CDemo() { //std::cout << "析构函数" << std::endl; } void print(std::string str) { std::cout << "CDemo::print "<<str << std::endl; } }; CDemo test() { CDemo demo; return demo; } CDemo test5(CDemo&& demo) { return demo; } CDemo test6(CDemo&& demo) { return demo; } void test4(CDemo demo) { } void test3(CDemo demo) { } void test2(CDemo demo) { std::cout << "call test3" << std::endl; test3(demo); std::cout << "call test4" << std::endl; test3(std::move(demo)); return; } bool write(std::vector<char> data) { return true; } int main() { std::cout << "call test" << std::endl; CDemo ok=test(); CDemo ok2; std::cout << "call =" << std::endl; ok2=ok; std::cout << "call test2" << std::endl; test2(ok); std::cout << "call test5" << std::endl; test5(std::move(ok2));//因为test5的参数声明为右值了 所以直接传入左值编译不过test5(ok2); 而test2则可以传入左值是调用复制,转入右值时调用移动 std::cout << "call test6" << std::endl; ok = test6(std::move(ok)); std::cout << "call test6" << std::endl; CDemo&& ok3 = test6(std::move(ok)); return 0; }
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
下面是输出结果
call test 移动函数 call = 赋值函数 call test2 拷贝函数 call test3 拷贝函数 call test4 移动函数 call test5 移动函数 call test6 移动函数 赋值函数 call test6 移动函数