首页 > 代码库 > c++11 右值引用
c++11 右值引用
http://blog.csdn.net/cpd92/article/details/50651700
http://www.tuicool.com/articles/i2qyyyB
move 就是右值引用,减少了copy和释放的过程,提高了程序性能。
#include <iostream>#include <string>#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& 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"); std::vector<MyString> vec; vec.push_back(MyString("World"));}
在 main 函数中,实现了调用拷贝构造函数的操作和拷贝赋值操作符的操作。MyString(“Hello”) 和 MyString(“World”) 都是临时对象,也就是右值。虽然它们是临时的,但程序仍然调用了拷贝构造和拷贝赋值,造成了没有意义的资源申请和释放的操作。如果能够直接使用临时对象已经申请的资源,既能节省资源,有能节省资源申请和释放的时间。这正是定义转移语义的目的。
增加转移构造,转移赋值运算符重载
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; }
增加了转移构造函数和转移复制操作符后,我们的程序运行结果为 :
Move Assignment is called! source: Hello Move Constructor is called! source: World
左值右值判断
#include <iostream>#include <string>#include<vector>using namespace std;template<typename T>void PrintT(T& t){ cout << "lvaue" << endl;}template<typename T>void PrintT(T && t){ cout << "rvalue" << endl;}template<typename T>void TestForward(T && v){ PrintT(v); PrintT(std::forward<T>(v)); PrintT(std::move(v));}int main (){ TestForward(1); int x = 1; TestForward(x); TestForward(std::forward<int>(x));}
std::forward会按参数原来的类型转发
std::move 转为右值
万能包装器
#include <iostream>#include <string>#include<vector>using namespace std;template<class Function, class... Args>inline auto FuncWrapper(Function && f, Args && ... args) -> decltype(f(std::forward<Args>(args)...)) { return f(std::forward<Args>(args)...);}void test0() { cout << "void" << endl; }int test1() { return 1; } int test2(int x) { return x; }string test3(string s1, string s2) { return s1 + s2; }void test() { FuncWrapper(test0); //没有返回值,打印1 cout<<FuncWrapper(test1)<<endl; //返回1 cout<<FuncWrapper(test2, 1)<<endl; //返回1 cout<<FuncWrapper(test3, "aa", "bb")<<endl; //返回"aabb"}int main(){ test();}
成员的emplace_back
c++11中大部分容器都加了一个emplace_back成员函数,vector中它的定义是这样的:
template< class... Args >void emplace_back( Args&&... args );
这里的Args&&是一个未定的引用类型,因此它可以接收左值引用和右值引用,它的内部也是调用了std::forward实现完美转发的。因此如果我们需要往容器中添加右值、临时变量时,用emplace_back可以提高性能。
c++11 右值引用
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。