理论
什么是引用限定符
我们知道,右值是没有内存实体的,也就是不能对它调用成员函数或者赋值。
但是有时我们会看到这样的调用:
string s1 = "abc", s2 = "def";
auto n = (s1 + s2).find('a'); //对右值调用成员函数
s1 + s2 = "wc"; //对右值赋值
其实这是无意义的。
C++11开始,仍然允许向右值调用成员函数、向右值赋值,但是提供了一种阻止的方法:引用限定符&和&&。
所谓引用限定符,就是在成员函数的后面添加 “&” 或者 “&&”,从而限制调用者的类型(左值还是右值)。
class demo{
int get_num(); // 默认情况下,成员对象既可以被左值,又可以被右值调用
int get_num()& ; // &限制被调用的成员对象必须是左值
int get_num()&& ; //&&限制被调用的成员对象必须是右值
}
class A{
A& operator=(const A&);
A& operator=(const A&) &;
A& operator=(const A&) &&;
}
注意,引用限定符只能用在成员函数上,不适用于静态成员函数和友元函数。
实验
#include <iostream>
class A {
public:
A(int x, int y, int z) : x(x), y(y),z(z) {}
int getX() & { return x; }
int getY() && { return y; }
int getZ() { return z; }
private:
int x;
int y;
int z;
};
int main() {
A a(1, 50, 100);
std::cout << a.getX() << std::endl;
// std::cout << std::move(a).getX() << std::endl; //错误,getX只能左值对象调
// std::cout << a.getY() << std::endl; //错误,getY只能右值对象调
std::cout << std::move(a).getY() << std::endl;
std::cout << a.getZ() << std::endl;
std::cout << std::move(a).getZ() << std::endl;
}
const和引用限定符
一个函数可以同时使用 const 和引用限定符,在此情况下,引用限定符必须跟随在const 限定符之后:
class Foo{
public:
Foo someMes() & const; //错误,const限定符必须在前
Foo someMes() const &; //正确,const限定符必须在前
};