为什么这个模板代码被允许违反C ++的私有访问说明符?

在下面的代码中,我在这里找到:

http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html

它似乎跨越了C ++的私有访问说明符。 它允许我调用私有函数并读取/写入私有数据成员。

搜索发现这个相关的问题,这是一个确认的GCC编译器错误

c ++模板似乎打破了访问说明符

所以我很自然地尝试使用那个人的测试代码。 有趣的是我的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)();
}

〜> ./a.out嘿,别碰我我是私人的!

〜> g ++ --version g ++(SUSE Linux)4.5.0 20100604 [gcc-4_5-branch revision 160292] Copyright(C)2010 Free Software Foundation,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;
}
链接地址: http://www.djcxy.com/p/10063.html

上一篇: Why is this template code allowed to violate C++'s private access specifier?

下一篇: Fragment backstack bug when replacing fragments in a transaction?