右值引用和成员函数
2024年1月1日 2024年1月1日
目前, 我们介绍了构造函数和赋值运算符的拷贝和移动版本
我们也可以同时提供成员函数的拷贝和移动版本
1void push_back(const X&); 2void push_back(X&&);
为StrVec::push_back定义移动版本
1void StrVec::push_back(string &&s) 2 { 3 chk_n_alloc(); 4 alloc.construct(first_free++, std::move(s)); 5 }
使用push_back
1StrVec vec; 2string s = "hello"; 3vec.push_back(s); // 匹配拷贝版本 4vec.push_back(done); // 匹配移动版本
对类对象调用成员函数时, 类对象可以是一个右值
1string s1 = "one", s2 = "another"; 2 3auto n = (s1 + s2).find(h); 4 5s1 + s2 = "wow!"; // string的赋值运算符
使用引用限定符限制对this提出要求: 左值或右值
reference qualifier
引用限定符 | this |
---|---|
& |
左值 |
&& |
右值 |
1class Foo 2{ 3public: 4 Foo &operator=(const Foo &) &; // 要求this为左值 5}; 6 7Foo &Foo::operator(const Foo &rhs) & 8{ 9 // ... 10 return *this; 11}
使用引用限定符
- 声明和定义时都需要给出, 和定义const成员函数相同
- 如果成员函数同时拥有const限定符和引用限定符, const限定符必须在前
const限定符和引用限定符都是用来修饰*this的
1class Foo 2{ 3public: 4 Foo someMem() & const; // 错误 5 Foo anotherMem() const &; // 正确 6};
成员函数重载
- 是否使用了const限定符
- 是否使用了引用限定符, 使用了何种引用限定符
如果一个成员函数有引用限定符, 则具有相同参数类别的所有版本都必须有引用限定符
当我们定义两个及以上具有相同名字和相同参数类别的成员函数, 要么对这些函数全部都加上引用限定符, 要么全部都不加