c++如何实现运算符重载_c++ operator重载规则【实战】

技术百科 尼克 发布时间:2026-01-27 浏览:
C++中sizeof、?:、::、.、.*五个运算符完全禁止重载;=、[]、()、->只能作为类的非静态成员函数重载;

哪些运算符能重载、哪些不能

不是所有运算符都能重载:sizeof?:(三目)、::(作用域)、.(成员访问)、.*(指针到成员)这五个完全禁止重载。其余大部分可以,但有隐含限制:比如 =[]()-> 只能作为类的非静态成员函数重载,不能是全局函数;而 +== 这类则既可成员也可友元(推荐友元,尤其对流操作符)。

常见误用是试图重载 . 来实现“透明代理”,结果编译报错 error: 'operator.' must be a non-static member function —— 实际上 C++ 不允许这么做,得改用 -> 配合智能指针或代理类模式绕过。

为什么 operator 必须用友元函数

因为左操作数是 std::ostream&(如 std::cout),它不属于你的类,你没法给 std::ostream 添加成员函数。所以必须写*局函数,再用 friend 打开类的私有访问权限:

class Vec {
    int x_, y_;
public:
    Vec(int x, int y) : x_(x), y_(y) {}
    friend std::ostream& operator<<(std::ostream& os, const Vec& v) {
        return os << "(" << v.x_ << ", " << v.y_ << ")";
    }
};

漏掉 friend 会导致编译错误 error: 'x_' is private within this context;不加 const Vec& 引用参数,则临时对象无法绑定,出现 error: binding reference to a temporary

赋值运算符 operator= 的深拷贝陷阱

默认生成的 operator= 是浅拷贝,遇到含裸指针的类会引发双重释放或悬空指针。手动重载时必须做三件事:

  • 自赋值检查:if (this == &other) return *this;
  • 释放当前资源(如有)
  • 深拷贝新资源,并返回 *this

更安全的做法是用“拷贝-交换”惯用法(copy-and-swap):

Vec& operator=(Vec other) { // 注意:传值,自动调用拷贝构造
    swap(*this, other);
    return *this;
}
friend void swap(Vec& a, Vec& b) noexcept {
    using std::swap;
    swap(a.x_, b.x_);
    swap(a.y_, b.y_);
}

这样天然规避自赋值问题,也保证异常安全。但注意:如果类里有大对象(如 std::vector),传值成本高,此时仍建议传统写法 + 显式深拷贝。

前置 vs 后置递增:++aa++ 的签名区别

前置递增(++a)返回引用,后置(a++)返回旧值,靠一个无用的 int 参数区分:

Vec& operator++() { // 前置
    ++x_; ++y_;
    return *this;
}
Vec operator++(int) { // 后置:int 是占位符,不使用
    Vec old = *this;

++(*this); // 复用前置逻辑 return old; }

常见错误是把后置写成 Vec& operator++(int) —— 返回局部对象的引用,导致未定义行为;或者忘记参数 int,编译器会把它和前置重载冲突,报错 redefinition of 'operator++'

真正难处理的是当类管理动态内存时,后置递增的拷贝成本可能很高,这时候得权衡是否禁用后置版本(删掉它,或只提供前置),避免用户无意中写出低效代码。


# 的是  # 这类  # 把它  # 很高  # 都能  # 也可  # 如有  # Error  # 对象  # c++  # if  # int  # 函数重载  # 区别  # 指针  # stream  # 报错  # 为什么  # Static  # function  # red  # private  # this  # operator  # 成员函数  # 作用域  # 空指针  # 运算符  # const  # copy  # 编译错误  # 用友  # 运算符重载  # 赋值运算符  # 引用参数 


相关栏目: <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 AI推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 SEO优化<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 技术百科<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 谷歌推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 百度推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 网络营销<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 案例网站<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 精选文章<?muma echo $count; ?>

相关推荐

在线咨询

点击这里给我发消息QQ客服

在线咨询

免费通话

24h咨询:4006964355


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部