欢迎光临
我们一直在努力

深入理解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;
}

赞(0)
未经允许不得转载:171主机测评 » 深入理解C++ 重载 <十二> 重载按位与运算符&
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址