拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

深入理解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; }
返回列表