yaw*_*w x -1 c++ templates boost c++-loki
我想在不修改 .h 文件的情况下访问私有成员。这是 .h 文件的示例
class X
{
private:
class A
{...};
vector<A> arr;
}
Run Code Online (Sandbox Code Playgroud)
问:如何访问 X::arr ?
class X
{
private:
int a;
};
template<typename Tag, typename Tag::type Member>
struct XAccessor
{
friend typename Tag::type get(Tag)
{
return Member;
}
};
struct X_A
{
typedef int X::* type;
friend type get(X_A);
};;
template struct XAccessor<X_A, &X::a>;
...
auto x = new X;
x->*get(X_A())=11;
...
Run Code Online (Sandbox Code Playgroud)
我在网上找到了这种方法,但是当我更改typedef int X::* type为时typedef vector<X::A> X::* type,它给了我一个错误,说X::A无法访问。
如果您可以窃取数据成员指针,则可以从中提取类型。这是一个对原始版本进行零修改的解决方案X。
假设我们有一个X无法修改的类,其中包含 private 类型的私有数据成员Hidden。在你的例子中,Hidden = std::vector<A>.
class X
{
private:
struct Hidden {};
Hidden a;
};
Run Code Online (Sandbox Code Playgroud)
我们可以创建一个返回数据成员指针的函数X::*a,而无需命名类型X::Hidden:
// the following three declarations give us a data member pointer to X::a
auto steal();
template <auto Ptr>
struct Thief {
friend auto steal() {
return Ptr;
}
};
// explicit instantiation of specialization Thief<&X::a>
template struct Thief<&X::a>;
Run Code Online (Sandbox Code Playgroud)
这样做的原因是显式实例化模板时禁用成员访问限制,因此Thief<&X::a>不会编译失败。这是有意设计的,因为否则您将无法显式实例化任何涉及非公共成员的模板。
Thief定义了一个隐藏的friend steal(),它返回数据成员指针,并充当封装的“越狱”。
steal()只是一个自由函数,不包含&X::a任何X::Hidden模板参数或函数参数,因此没有任何东西限制我们对它的访问。
我们还创建了一个类型特征,以便我们可以从此指针中提取数据类型:
// trait which lets us extract Hidden from a data member pointer
template <typename T>
struct member_type;
template <typename C, typename M>
struct member_type<M C::*> {
using type = M;
};
Run Code Online (Sandbox Code Playgroud)
最后,我们能够访问私有类型X::Hidden和私有数据成员X::a:
// X_Hidden = X::Hidden
using X_Hidden = member_type<decltype(steal())>::type;
// steal private data member at runtime
X_Hidden get_a(const X &x) {
X_Hidden X::*a = steal();
return x.*a;
}
Run Code Online (Sandbox Code Playgroud)