zoukankan      html  css  js  c++  java
  • C++的左值与右值引用

    C++的左值与右值引用

    左值引用

    左值引用是左值对象的一个别名,定义一个引用必须进行初始化。

    左值引用相当于一个指针常量。 

    int a = 10;
    int &b = a;
    int * const p = &a;

    左值引用无法作用于非左值(如立即数,不能取地址)

    int &b = 520; //错误的 520在寄存器中

    若想解决上述问题则要加上const修饰

    const int &b = 520; 
    
    //相当于
    const int temp=520const int &b=temp;

    左值引用必要求被引用的值可以取地址,如果无法去地址,可以使用常量引用。

    右值引用

    右值引用用来引用临时对象(立即数、临时对象等)

    右值引用格式:

    类型 && 引用名 = 右值表达式;

    int && n = 15;

    右值引用和常量引用所做的事情相同,产生一个临时量来存储常量。

    区别是右值引用可以进行修改操作,而常量引用不能进行修改。

    目的:

    利用右值引用特性减少对象的构造和析构操作以提高效率。

    class Stack 
    {
    public:
        Stack(int size = 1000)
            :msize(size),mtop(0)
        {
            cout << "Stack(int)" << endl;
            mpstack = new int[size];
        }
        ~Stack()
        {
            cout << "~Stack()" << endl;
            delete[] mpstack;
            mpstack = nullptr;
        }
        //Stack(const Stack&src)
        //    :msize(src.msize), mtop(src.mtop)
        //{
        //    cout << "Stack(const Stack& src)" << endl;
        //    mpstack = new int[src.msize];
        //    for (int i = 0; i < mtop; ++i) 
        //    {
        //        mpstack[i] = src.mpstack[i];
        //    }
        //}
        Stack(Stack&&src)
            :msize(src.msize), mtop(src.mtop)
        {
            cout << "Stack(Stack&&)" << endl;
            //此处没有重新开辟内存拷贝数据
            //把src的资源直接给当前对象
            //再把src置空
            mpstack = src.mpstack;
            src.mpstack = nullptr;
        }
    
    
        //Stack& operator= (const Stack& src)
        //{
        //    cout << "operator=" << endl;
        //    if (this == &src)
        //        return *this;
    
        //    delete[] mpstack;
        //    msize = src.msize;
        //    mtop = src.mtop;
        //    mpstack = new int[src.msize];
        //    for (int i = 0; i < mtop; ++i) 
        //    {
        //        mpstack[i] = src.mpstack[i];
        //    }
        //    return *this;
        //}
        Stack& operator= (Stack&& src)
        {
            cout << "operator=(Stack&&)" << endl;
            if (this == &src)
                return *this;
    
            delete[] mpstack;
            msize = src.msize;
            mtop = src.mtop;
    
            //此处没有重新开辟内存拷贝数据
            //把src的资源直接给当前对象
            //再把src置空
            mpstack = src.mpstack;
            src.mpstack = nullptr;
    
            return *this;
        }
    
        int getSize()
        {
            return msize;
        }
    
    private:
        int *mpstack;
        int mtop;
        int msize;
    };
    
    Stack Getstack(Stack & stack)
    {
        Stack tmp(stack.getSize());
        return tmp;
    }
    
    
    int main() {
        
        {
            Stack s;
            cout << "  " << endl;
            s = Getstack(s);
        }
            system("pause");
        return 0;  
    }

    运行结果如下所示:

    Stack s;(调用构造函数)  -->  Stack Getstack(Stack & stack) (调用构造函数)  
    --> Getstack(s);(调用拷贝构造函数) --> s = Getstack(s);(调用赋值构造函数)
     

    参考链接:

    https://zhuanlan.zhihu.com/p/97128024

  • 相关阅读:
    ACTIVE OBJECT 模式
    Node.js
    WordPress — 突破性能瓶颈,使用 WordPress 站群做 SEO 推广
    HttpRequest.Item 属性 和 HttpRequest.QueryString 属性的区别!
    Regex.Replace 方法的性能!(090625最新修改)
    FACTORY 模式
    Indexof String By Byte[]
    [11]DIP:依赖倒置原则
    C#.Net Winform skin 皮肤 大全(转)
    C# 情缘
  • 原文地址:https://www.cnblogs.com/dreammmz/p/13416584.html
Copyright © 2011-2022 走看看