C++实现类成员在不同类中分别为只读/可写状态的最优方案
最佳实现方案(编译期权限令牌方案)
本方案所有权限校验全部在编译期完成,无任何运行时开销,不符合权限的写操作会直接触发编译报错,且权限粒度可以精确到单个成员,完全匹配需求。
实现逻辑
- 为每个需要区分写权限的成员定义专属的空结构体作为权限令牌,仅将授权可写的类设为对应令牌的友元,确保只有授权类能实例化该令牌
- 仓库类将所有成员变量设为私有,对外公开无权限要求的读方法,以及需要传入对应权限令牌才能调用的写方法
- 非授权类调用写方法时,因为无法构造对应令牌参数,会直接触发编译错误
完整示例代码
#include <iostream> using namespace std; // 提前声明授权类 class A; class B; // 定义权限令牌:只有友元类能构造 struct WritableA_Token { friend class A; private: WritableA_Token() = default; }; struct WritableB_Token { friend class B; private: WritableB_Token() = default; }; class myRepository { private: int writableIn_A; int writableIn_B; public: // 所有读方法公开,任意类都能调用 int get_writableIn_A() const { return writableIn_A; } int get_writableIn_B() const { return writableIn_B; } // 写方法需要传入对应权限令牌,令牌仅做权限校验无需实际使用 void set_writableIn_A(WritableA_Token, int val) { writableIn_A = val; } void set_writableIn_B(WritableB_Token, int val) { writableIn_B = val; } }; // 全局仓库实例 myRepository repository; class A { public: void f_A() { // 读操作全部正常 cout << repository.get_writableIn_A(); // ok cout << repository.get_writableIn_B(); // ok // 仅授权成员可写,传入对应令牌即可 repository.set_writableIn_A(WritableA_Token{}, 10); // ok // 下方注释代码会编译报错:WritableB_Token构造函数私有,A无法构造 // repository.set_writableIn_B(WritableB_Token{}, 20); } }; class B { public: void f_B() { // 读操作全部正常 cout << repository.get_writableIn_A(); // ok cout << repository.get_writableIn_B(); // ok // 仅授权成员可写,传入对应令牌即可 repository.set_writableIn_B(WritableB_Token{}, 20); // ok // 下方注释代码会编译报错:WritableA_Token构造函数私有,B无法构造 // repository.set_writableIn_A(WritableA_Token{}, 10); } };
方案优势
- 权限粒度精确:可以针对单个成员配置可写的类,不会出现普通友元方案中授权类可以访问所有私有成员的粗粒度权限问题
- 无运行时损耗:所有校验逻辑全部在编译期完成,运行时性能和直接访问成员完全一致
- 报错时机早:不符合权限的写操作会在编译阶段直接提示错误,不会留到运行时才暴露问题
内容的提问来源于stack exchange,提问作者aminM
相关产品推荐
相关产品推荐

