Friend函数访问静态库中定义的类的私有成员
Friend function access the private members of class defined in static library
我有一个用C++编写的静态库。我还得到了静态库中定义的类的头文件。
我可以访问在类声明中引入友元函数的静态库中定义的类的私有成员吗?
您的意思是要更改库附带的头文件?不能保证在那里添加friend
声明会起作用。您可能会弄乱链接部分,即使您的编译器说可以。
此外,如果这些成员是private
,则不能访问它们。
从技术上讲,使用不同的令牌序列以不同的翻译单位定义同一实体(此处为类)是未定义的行为。
无论你使用什么技术,只要它改变了构成它的令牌的顺序,从标准的角度来看,它都是邪恶的(尽管在实践中可能有效)。
约翰内斯发现了一种在尊重标准的同时做到这一点的方法。这是基于这样一个事实,即即使a
是类A
中的私有属性,&A::a
也可以在不能写入A.a
的上下文中写入(可能是标准中的疏忽?)。
核心方法:
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// use
struct A {
A(int a):a(a) { }
private:
int a;
};
// tag used to access A::a
struct A_f {
typedef int A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*get(A_f()) << std::endl;
}
简化扩展:
template<typename Tag, typename Member>
struct TagBase {
typedef Member type;
friend type get(Tag);
};
struct A_f : TagBase<A_f, int A::*> { };
编辑:
这个技巧(有趣的是)被标准明确允许
§14.7.2/12通常的访问检查规则不适用于用于指定显式实例化的名称。[…]
相关文章:
- 类模板静态数据成员定义/声明/初始化
- 默认移动成员定义为已删除,而未定义特殊成员?
- 条件C++类成员定义
- 将类类型成员定义为公共和私有之间有什么区别?
- 有没有办法为静态对象成员定义一个符合开关标准的常量?
- C 不能将带有父类指针作为类型的静态模板成员定义引用
- 如何在 .cpp 文件中为私有类成员定义 friend 运算符<<而不是在标头中
- 为类模板的单个成员定义专用化
- 使用命名空间进行函数成员定义
- C 类静态结构成员定义
- C 替代成员定义
- C++:如何将数据成员定义为 const
- 模板超类的静态成员定义
- 如何为联合成员定义typedef
- 为类模板的枚举成员定义 std::hash
- 在越界成员定义的类型说明符中是否可以省略typename
- 更改成员定义的顺序会破坏内存
- 为什么不允许将类成员定义的' static '关键字放在命名空间范围内?
- 我是否应该在将实现委托给子类的类中包含成员定义?
- 在非限定id后的静态数据成员定义中使用的名称