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 后置递增:++a 和 a++ 的签名区别
前置递增(++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; ?>
】
相关推荐
- c# 如何用c#实现一个支持优先级的任务队列
- Win11怎么设置按流量计费_Win11限制后台流
- Windows10蓝屏代码DPC_WATCHDOG
- Windows服务持续崩溃怎样修复_系统服务保护机
- win11如何清理传递优化文件 Win11为C盘瘦
- Win11如何设置开机自动联网 Win11宽带连接
- Win11怎么查看局域网电脑_Windows 11
- 获取 PHP 文件最后修改时间的正确方法
- Win11如何设置计划任务 Win11定时执行程序
- Win11如何设置电源计划_Win11电源计划优化
- 跨文件调用类方法怎么用_php作用域操作符与自动加
- Windows11怎么用“记事本”自动换行与编码
- Win11怎么开启远程桌面连接_Windows11
- Go 中 defer 语句在 goroutine
- 如何在 Go 同包不同文件中正确引用结构体
- 作用域操作符会影响性能吗_php静态调用性能分析【
- Windows10电脑怎么设置自动连接WiFi_W
- Win11怎么更改默认打开方式_Win11关联文件
- c++如何实现一个高性能的环形队列(Ring Bu
- Python异步编程高级项目教程_asyncio协
- Win11怎么更改电脑名称_Windows 11修
- PowerShell怎么创建复杂的XML结构
- Mac怎么查看活动监视器_理解Mac进程和资源占用
- Win11怎么关闭搜索历史_Win11清除任务栏搜
- Go 中的 := 运算符:类型推导机制与使用边界详
- MAC如何安装Git版本控制工具_MAC开发环境配
- 如何将文本文件中的竖排字符串转换为横排字符串
- php与c语言在嵌入式中有何区别_对比两者在硬件控
- 如何使用Golang读取日志文件_Golang b
- Mac自带的词典App怎么用_Mac添加和使用多语
- Win11怎么禁用键盘自带键盘_Win11笔记本禁
- Win11如何设置鼠标灵敏度_Win11鼠标灵敏度
- 如何在 Go 结构体中正确初始化 map 字段
- Windows10系统服务优化指南_Win10禁用
- Go 中 := 短变量声明的类型推导机制详解
- Win11如何卸载OneDrive_Win11卸载
- php订单日志怎么记录评价_php记录订单评价日志
- 如何使用Golang reflect检查方法数量_
- Python安全爬虫设计_IP代理池与验证码识别策
- Win11怎么关闭键盘按键音_Win11禁用打字声
- c++如何连接Redis c++ hiredis库
- Win11如何开启telnet服务 Win11启用
- Win11怎样安装企业微信_Win11安装企业微信
- Mac电脑进水了怎么办_MacBook进水后紧急处
- Windows10怎么用“讲述人”读屏辅助 Win
- Python大型项目拆分策略_模块化解析【教程】
- C++如何使用std::optional?(处理可
- 如何在Golang中使用time处理时间_Gola
- Win11怎么关闭专注助手 Win11关闭免打扰模
- 如何使用正则表达式提取以编号开头、后接多个注解的逻


QQ客服