我有一个用C ++编写的静态库。我还获得了静态库中定义的类的头文件。
我可以访问静态库中定义的类的私有成员,在类声明中引入友元函数吗?
答案 0 :(得分:1)
您的意思是您想要更改库附带的标头?绝不保证添加friend
声明会起作用。 可能会弄乱链接部分,即使您的编译器说它没问题。
此外,如果这些成员是private
,则您只是不访问它们。
答案 1 :(得分:1)
技术上未定义的行为使用不同的令牌序列来定义不同翻译单元中的同一实体(此处为类)。
无论你使用什么技术,只要它改变构成它的令牌序列,从标准的角度来看它是邪恶的(尽管可能在实践中起作用)。
Johannes discovered a way在尊重标准的同时这样做。它基于以下事实:即使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::*> { };
修改强>:
这个技巧是(有趣的)标准
explicitly allowed§14.7.2/ 12 通常的访问检查规则不适用于用于指定显式实例化的名称。 [...]