在C++中,引用限定符用于修饰类的非静态成员函数,用来指定该函数只能被特定值类别的对象调用,主要分为左值引用限定符&和右值引用限定符&&,这一特性从C++11开始引入,在C++26中依然保持稳定的语法规则。

引用限定符的基本语法
为成员函数添加引用限定符的语法非常简单,只需要在成员函数的参数列表之后、const限定符(如果有)之后、函数体之前添加对应的限定符即可。如果同时有const和引用限定符,const需要放在前面。
基本语法格式如下:
class MyClass {
public:
// 左值引用限定符,只能被左值对象调用
void func_lref() & {
// 函数逻辑
}
// 右值引用限定符,只能被右值对象调用
void func_rref() && {
// 函数逻辑
}
// 同时有const和引用限定符,const在前
void func_const_rref() const && {
// 函数逻辑
}
};
引用限定符的调用规则
添加了引用限定符的成员函数,调用时会受到对象值类别的限制,具体规则如下:
- 没有引用限定符的成员函数,既可以被左值对象调用,也可以被右值对象调用
- 添加了&限定符的成员函数,只能被左值对象调用,右值对象调用会编译报错
- 添加了&&限定符的成员函数,只能被右值对象调用,左值对象调用会编译报错
下面通过一个完整的示例来演示调用规则:
#include <iostream>
#include <string>
class Data {
private:
std::string content;
public:
Data(std::string str) : content(str) {}
// 无引用限定符
void print() {
std::cout << "普通函数调用,内容:" << content << std::endl;
}
// 左值引用限定符
void print_lref() & {
std::cout << "左值限定函数调用,内容:" << content << std::endl;
}
// 右值引用限定符
void print_rref() && {
std::cout << "右值限定函数调用,内容:" << content << std::endl;
}
};
int main() {
Data obj("hello"); // obj是左值
obj.print(); // 正常调用,普通函数无限制
obj.print_lref(); // 正常调用,左值调用左值限定函数
// obj.print_rref(); // 编译报错,左值不能调用右值限定函数
Data("world").print(); // 正常调用,临时对象是右值,可调用普通函数
// Data("world").print_lref(); // 编译报错,右值不能调用左值限定函数
Data("world").print_rref(); // 正常调用,右值调用右值限定函数
return 0;
}
引用限定符的常见使用场景
1. 避免不必要的拷贝
当成员函数需要返回对象内部的资源时,如果是右值对象调用,可以直接转移资源所有权,避免拷贝。比如下面的字符串获取函数:
#include <iostream>
#include <string>
class Text {
private:
std::string text;
public:
Text(std::string str) : text(str) {}
// 左值调用时,返回拷贝,避免修改原对象内容
std::string get_text() & {
return text;
}
// 右值调用时,直接转移资源,避免拷贝
std::string get_text() && {
return std::move(text);
}
};
int main() {
Text t1("test");
std::string s1 = t1.get_text(); // 调用左值版本,返回拷贝
std::cout << "s1: " << s1 << std::endl;
std::string s2 = Text("temp").get_text(); // 调用右值版本,转移资源
std::cout << "s2: " << s2 << std::endl;
return 0;
}
2. 限制危险操作
有些操作如果作用于临时对象可能会导致未定义行为,比如返回对象内部裸指针的函数,如果临时对象被销毁,指针就会悬空。这时候可以用左值引用限定符限制只能被左值调用:
#include <iostream>
class Buffer {
private:
char* data;
int size;
public:
Buffer(int n) : size(n) {
data = new char[n];
}
~Buffer() {
delete[] data;
}
// 只允许左值对象获取裸指针,避免临时对象销毁后指针悬空
char* get_raw_ptr() & {
return data;
}
};
int main() {
Buffer buf(10);
char* p1 = buf.get_raw_ptr(); // 正常,buf是左值
// char* p2 = Buffer(10).get_raw_ptr(); // 编译报错,临时对象是右值,不能调用
return 0;
}
注意事项
- 引用限定符只能用于类的非静态成员函数,静态成员函数不能使用
- 如果声明了带引用限定符的成员函数,对应的函数定义也需要加上相同的引用限定符,否则会编译报错
- 引用限定符可以和const、volatile限定符组合使用,顺序必须是const/volatile在前,引用限定符在后
- 重载成员函数时,引用限定符可以作为重载的依据,比如上面的get_text函数就有两个重载版本
引用限定符是C++中提升代码安全性和性能的重要特性,合理使用可以明确函数的调用约束,减少潜在的错误,同时优化临时对象的操作效率。
C++rvalue_ref_qualifiersmember_functionreference_qualifier修改时间:2026-06-19 15:57:26