导读:本期聚焦于小伙伴创作的《C++如何为成员函数添加引用限定符?引用限定符的作用和使用场景是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何为成员函数添加引用限定符?引用限定符的作用和使用场景是什么》有用,将其分享出去将是对创作者最好的鼓励。

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

C++如何为成员函数添加引用限定符?引用限定符的作用和使用场景是什么

引用限定符的基本语法

为成员函数添加引用限定符的语法非常简单,只需要在成员函数的参数列表之后、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

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。