为什么允许此模板代码违反C++的专用访问说明符?
Why is this template code allowed to violate C++'s private access specifier?
在下面的代码中,我在这里找到:
http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html似乎正好跨过了c++的私有访问说明符。它允许我调用私有函数和读/写私有数据成员。
搜索SO发现这个相关的问题,这是一个确认的GCC编译器错误
c++模板似乎破坏了访问说明符
所以我很自然地尝试使用那个家伙的测试代码。有趣的是,我的gcc 4.5编译器确实有这个错误(它接受代码并打印私有信息),尽管它在gcc 4.3和我使用4.5中被报告。
不管怎样,然后我去了Comeau在线编译器,一些线程的回应说他们尝试过。我确认Comeau 不接受问题中的代码,但是它确实接受下面我的代码。
所以最终我的问题是,我偶然发现一个bug在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)();
}
~> ./a.o ut嘿,别碰我,我是隐私!
~> g++——versiong++ (SUSE Linux) 4.5.0 20100604 [gcc-4_5-branch revision 160292]版权所有:自由软件基金会,Inc.
正如Loki Astari所说,public和private只是编译器的语义,因此它可以警告你没有按预期的方式使用代码。
我不怎么使用方法指针(如果有的话),所以我没有耐心完全弄清楚这一点。但这和下面几种方法的混合没有什么不同。也就是说,使用指针逻辑指向你想要的任何内存位,强制转换函数和方法并滥用它们。
#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;
}
- 如何在C++的专用模板类中访问模板类成员字段
- 父访问子专用/受保护
- 无法访问专用函数
- 从c++中的方法访问指向对象的专用指针数组
- 运算符<<重载时无法访问专用成员(指定指针)
- 从专用化访问模板参数
- 避免强制转换以访问派生类的专用成员
- 访问专用模板的私有/继承成员变量
- 多个级别的专用和公共异常访问
- 从主访问指向数组的专用指针
- 访问专用模板中嵌套好友类的私有成员
- 从类外部访问专用虚拟函数
- 访问专用数据成员
- 无法访问QXmlStreamReader的专用成员(运算符=)
- 继承的静态函数能否访问重写的静态专用数据成员
- 类专用成员-数组访问失败
- 为什么允许此模板代码违反C++的专用访问说明符?
- 在 OpenMP 中访问线程的专用内存
- 模板专用化中出现受保护成员访问错误
- 循环访问类模板的显式专用化