zoukankan      html  css  js  c++  java
  • 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] = '';
        }
    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); //没有返回值,打印void
        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可以提高性能。

  • 相关阅读:
    Mysql String Functions
    Array JSON
    $(document).ready vs $(window).load vs window.onload
    jquery,返回到顶部按钮
    html5 教程网站
    js,replace() 和 正则表达式(regular expression)
    设置 textarea 默认滑动到底部
    工作常用英语单词整理2
    工作常用英语单词整理1
    javascript,jquery代码规范
  • 原文地址:https://www.cnblogs.com/yuguangyuan/p/5860626.html
Copyright © 2011-2022 走看看