C++的左值与右值引用
左值引用
左值引用是左值对象的一个别名,定义一个引用必须进行初始化。
左值引用相当于一个指针常量。
int a = 10; int &b = a; int * const p = &a;
左值引用无法作用于非左值(如立即数,不能取地址)
int &b = 520; //错误的 520在寄存器中
若想解决上述问题则要加上const修饰
const int &b = 520; //相当于 const int temp=520; const 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);(调用赋值构造函数)
参考链接: