news 2026/10/2 20:08:44

深入理解C++ 重载 <十二> 重载按位与运算符

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入理解C++ 重载 <十二> 重载按位与运算符

C++ 重载按位与运算符operator&详解

一、什么是按位与运算符的重载

C++ 中的&是一个二元运算符,默认对整数执行按位与:

cpp

int a = 0b1100; int b = 0b1010; int c = a & b; // 0b1000

和+、-、|一样,&也可以被重载,让用户自定义类型也能用&运算。

cpp

class T { public: T operator&(const T& rhs) const { // 返回一个新的 T } };

调用形式:

cpp

T x, y; T z = x & y; // 等价于 x.operator&(y)

二、为什么按位与的重载比取地址"安全"得多

对比一元operator&(取地址),二元operator&的重载要温和很多:

对比项一元operator&二元operator&
破坏语言假设是(地址语义)否
影响标准库严重无
常见性极少较常见
推荐度强烈不建议视场景而定

二元operator&只是一个普通运算符重载,和operator+完全对等,不会破坏语言机制。


三、典型应用场景

场景说明
位标志 (bit flags)Permissions、FileMode等组合与查询
集合运算用位图表示集合,&表示交集
DSL / 表达式模板构建查询表达式,如filter & condition
矩阵/向量按元素与数值计算库中按元素逻辑与
智能位集类自定义bitset风格的类

其中位标志是最经典、最实用的场景。

#include <iostream> #include <string> // 权限标志(用无符号整数表示每一位) enum class Perm : unsigned { None = 0, Read = 1u << 0, // 001 Write = 1u << 1, // 010 Execute = 1u << 2, // 100 }; // 权限集合类 class Permissions { public: // 默认构造:无权限 Permissions() : bits_(0) {} // 从单个权限构造 Permissions(Perm p) : bits_(static_cast<unsigned>(p)) {} // 从原始位构造(显式,避免隐式转换) explicit Permissions(unsigned bits) : bits_(bits) {} // ============ 重载按位与 & ============ // 语义:返回两个权限集合的"交集" Permissions operator&(const Permissions& rhs) const { return Permissions(bits_ & rhs.bits_); } // ============ 重载按位与赋值 &= ============ Permissions& operator&=(const Permissions& rhs) { bits_ &= rhs.bits_; return *this; } // ============ 顺带重载 | 和 |= ============ Permissions operator|(const Permissions& rhs) const { return Permissions(bits_ | rhs.bits_); } Permissions& operator|=(const Permissions& rhs) { bits_ |= rhs.bits_; return *this; } // 转 bool:非空即可判断为 true explicit operator bool() const { return bits_ != 0; } // 判断是否包含某个权限 bool has(Perm p) const { return (bits_ & static_cast<unsigned>(p)) != 0; } unsigned raw() const { return bits_; } private: unsigned bits_; }; // 让 `Permissions & Perm` 也能用(对称性) inline Permissions operator&(Permissions lhs, Perm rhs) { return lhs & Permissions(rhs); } int main() { // 组合:Read | Write Permissions rw = Permissions(Perm::Read) | Permissions(Perm::Write); std::cout << "rw.bits = " << rw.raw() << "\n"; // 3 // 1) 用 & 求交集:rw & Read Permissions onlyRead = rw & Permissions(Perm::Read); std::cout << "onlyRead.raw = " << onlyRead.raw() << "\n"; // 1 // 2) 用 if (p & mask) 做权限检查 if (rw & Permissions(Perm::Read)) { std::cout << "有读权限\n"; } if (!(rw & Permissions(Perm::Execute))) { std::cout << "没有执行权限\n"; } // 3) 用 has() 更直观 std::cout << "has(Write)? " << rw.has(Perm::Write) << "\n"; // 1 std::cout << "has(Execute)? " << rw.has(Perm::Execute) << "\n"; // 0 // 4) 用 &= 原地取交集 Permissions p = Permissions(Perm::Read) | Permissions(Perm::Write); p &= Permissions(Perm::Read); std::cout << "p.raw = " << p.raw() << "\n"; // 1 return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 20:04:29

Ubuntu 20.04 安装 OpenClaw 全攻略:从环境配置到模型接入与报错排查

1. 安装前要摸清的底细如果你搜到这个标题&#xff0c;大概率已经有两个预判&#xff1a;一是觉得“Ubuntu 20 装个开源工具能有多难”&#xff0c;二是卡在某个报错里出不来。我先后在物理机、虚拟机、WSL2 里完整跑过 OpenClaw&#xff0c;也被 npm 权限、Node 版本、WSL 报错…

作者头像 李华
网站建设 2026/10/2 20:02:47

CSS字体属性全攻略:字体栈、字号、字重与复合属性详解

CSS字体属性大概是前端入门时最早接触、却最容易稀里糊涂带过去的一块。很多人写 font-family 就手打一个 Arial&#xff0c;写 font-size 就随便给个 14px&#xff0c;等到做真实项目才发现&#xff1a;字体栈顺序不对、中文乱码、 font-weight: bold 在部分浏览器里根本…

作者头像 李华
网站建设 2026/10/2 19:58:10

a标签href与target全解析:从基础用法到安全坑位

1. 一个被写错的属性名&#xff0c;让我重新审视了a标签先讲个真事儿。上周帮一个前端群里的朋友排查问题&#xff0c;他写的链接死活不跳转&#xff0c;代码如下&#xff1a;<a herf"https://example.com">点击跳转</a>我一眼就看到了问题&#xff1a;h…

作者头像 李华
网站建设 2026/10/2 19:58:07

告别Vivado编辑器:用VSCode打造高效Verilog开发与仿真工作流

每次在Vivado里写Verilog&#xff0c;我都觉得回到了十年前——编辑器没有代码补全&#xff0c;信号跳转靠眼力&#xff0c;语法错误要到综合阶段才爆出来。后来花了一个周末&#xff0c;把Vivado和VSCode串成了完整工作流&#xff0c;从此写RTL、跑仿真、查时序全在VSCode里完…

作者头像 李华