zoukankan      html  css  js  c++  java
  • [C++] 右值引用

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    class A {
    public:
        char *p;
        A() {
            p = new char[3];
        };
    
        A(const A& a) {
            p  = new char[3];
            for(int i = 0; i < 3; ++i) {
                p[i] = a.p[i];
            }
        }
        
        // 移动构造
        A(A&& a) {
            cout << "in move constructor" << endl;
            p = a.p;
            a.p = nullptr;    
        }
        
        // 移动赋值
        A& operator=(A&& a) {
            cout << "in move = operator" << endl;
            p = a.p;
            a.p = nullptr;
            return *this;
        }
    
        ~A() {};
    };
    
    int main()    
    {
    
        /** 1. 对基础类型变量(如int)进行move操作, 
            move前后的变量(i, rr)指向了同一块内存空间;
            如下例
            (1) int &&rr = move(i); 之后i, rr对应同一块内存,值均为22;
            (2) i = 44; 之后,i,rr的值均为44
         */
        int i = 22;
        int &&rr = move(i);
    
        cout << "ori i = 22, move to rr" << endl;
        cout << "i = " << i << endl;     // 22
        cout << "rr = " << rr << endl;   // 22
        
        cout << endl;
    
        cout << "after i = 44" << endl;
        i = 44;
        cout << "i = " << i << endl;      // 44
        cout << "rr = " << rr << endl;    // 44
        
        cout << endl;
    
        /** 2. 对含有指针的类进行move操作
            (1) 为什么需要move
            类中如果含有指针,那么对类对象在进行拷贝时,要思考进行深拷贝还是浅拷贝;
            如果进行浅拷贝,对于类中的指针类型,只能copy指针的地址,并不能复制指针指向的内容;
            如果进行深拷贝,对于类中的指针类型,则重新开辟了一块内存空间,copy指针指向的内容;
            但是对于一些被copy之后不会再被用到的类对象,却还占据着空间,
            于是希望引入"move",把原对象的内存"偷"过来,接管对原对象内存空间的管理权,
            以达到节约开销,提高性能的目的;
    
            (2) 如何move
            对于类中的指针,在调用时一般是不可见的(如private类型的),
            所以需要类的构造者在设计构造函数时,考虑如果将其进行拷贝or赋值操作时应如何处理指针。
            
            对于move操作,有移动构造和移动赋值2种;
            移动构造:在声明定义时进行初始化;见class A中的 A(A&& a) 
            移动赋值:用=赋值;见class A 中的 A& operator=(A&& a)
    
            如果使用move,开发者要设计好类中的以上2中操作,一般是:
            再创建一个新的指针,
            用新指针地址 = 被复制对象的对应指针地址,
            将被复制对象的对应指针 指向 设置为空。
         */

    A a; char *s = "ab"; a.p = s; cout << "a.p = " << endl; for(int i = 0; i < 3; ++i) { // 这里转int可以看到字符串是否以结束 cout << int(a.p[i]) << " "; // 97 98 0 } cout << endl; /////// 1. 普通的拷贝构造 ////////// A b(a); cout << "b.p = " << endl; for(int i = 0; i < 3; ++i) { cout << b.p[i] << " "; // a b } cout << endl; cout << endl; /////// 2. 移动赋值 c = move(a); ////////// // 这里将 char* 强转 int* 为了获取指针p的地址 // 如果不强转, C++在对char*输出时,会默认输出指针所指向地址的值(ex."ab") // 下例输出: // in move = operator // after A c = move(a) // a.p = 0x0 // c.p = 0x10e3d0edb A c; c = move(a); cout << "after A c = move(a)" << endl; cout << "a.p = " << (int*)a.p << endl; cout << "c.p = " << (int*)c.p << endl; /////// 3. 移动构造 A e(move(d)); ////////// // in move constructor // after e(move(d)) // d.p = 0x0 // e.p = 0x10e3d0f09 A d; char *s2 = "cd"; d.p = s2; A e(move(d)); cout << "after e(move(d))" << endl; cout << "d.p = " << (int*)d.p << endl; cout << "e.p = " << (int*)e.p << endl; return 0; }

  • 相关阅读:
    VS2005进行WAP开发中的控件排列问题
    WAP中图像列表的设计
    List分页存在的问题
    vs.net2005下的WAP开发之设备仿真器
    用户控件中RedirectToMobilePage的使用
    ASP.NET网站发布问题
    asp.net开发WAP时表单提交的问题及粗略的解决
    如何在objectlist上显示两个字段的连接??
    VS2008 快捷键大全
    [翻译]25招改善你的jQuery [2]
  • 原文地址:https://www.cnblogs.com/shiyublog/p/13550257.html
Copyright © 2011-2022 走看看