在下面的代码中,我在这里找到:
http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html
它似乎跨越了C ++的私有访问说明符。它允许我调用私有函数和读/写私有数据成员。
搜索SO发现了这个相关的问题,这是一个确认的GCC编译器错误
c++ template seems to break access specifiers
很自然地,我尝试使用那个人的测试代码。有趣的是,我的gcc 4.5编译器确实有这个bug(它接受代码并打印私人信息),尽管它在gcc 4.3和我使用4.5中报告。
无论如何,我接着去了Comeau在线编译器,其中一些对该线程的回复表示他们尝试过。我确认Comeau 不接受该问题的代码,但 接受下面的代码。
所以最终我的问题是,我偶然发现了GCC和Comeau的C ++编译器中的错误吗?这是用VC ++编译的吗?如果它不是一个bug,有人可以解释它是如何工作的吗?我知道它能够声明一个静态成员函数指针并将其指向私有部分,但它是如何实现的呢?
杂项说明:是的,我知道实际上这样做非常非常糟糕。如果您声明成员数据ptr并允许您读取/写入私有数据,这也将起作用。一些奇怪的评论来自我试图将其标记为理解。我没有想到这个代码,我不相信它。我刚刚在谷歌上找到它。我可能没有足够的声誉点来回复评论,但我会读你所说的一切。谢谢你看看。#include <iostream>
using namespace std;
//--------------------------------------------
//
template<typename Tag>
struct result
{
/* export it ... */
typedef typename Tag::type type;
static type ptr;
};
// allocate space for the static member
template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;
//--------------------------------------------
template<typename Tag, typename Tag::type p>
struct rob : result<Tag>
{
/* fill it ... */
struct filler
{
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};
// allocate space for the static member
template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
//--------------------------------------------
struct A
{
private:
void f()
{
cout << "hey, don't touch me I'm private!" << endl;
}
};
struct Af
{
typedef void(A::*type)();
};
template class rob<Af, &A::f>;
int main()
{
A a;
(a.*result<Af>::ptr)();
}
〜&GT; ./a.out 嘿,不要碰我,我是私人的!
〜&GT; g ++ --version g ++(SUSE Linux)4.5.0 20100604 [gcc-4_5-branch revision 160292] 版权所有(C)2010 Free Software Foundation,Inc。
答案 0 :(得分:3)
正如Loki Astari所说,公共和私有只是编译器的语义,所以它可以告诉你,你没有按照你想要的方式使用你的代码。
我不太喜欢使用方法指针(如果有的话),所以我没有耐心去充分发现这一点。但是,混合使用以下内容并没有什么不同。也就是说,使用指针逻辑指向你想要的任何内存,并转换函数和方法并滥用它们。
#include <iostream>
using namespace std;
struct A
{
public:
void g()
{
cout << "value of i is " << this->i << endl;
}
void setJ(int newJ) {
j = newJ;
}
int i;
private:
int j;
};
int main() {
A a;
a.i = 5;
a.setJ(10);
// accessing private field j
cout << "value of j is " << *((&a.i)+1) << endl;
// creating a pointer to method g
void(A::*method)() = &A::g;
// changing it to be a function pointer
void(*function)(A*) = (void(*)(A*)) method;
// using function pointer to call A::g
function(&a);
return 0;
}