c++ - 为什么允许此模板代码违反 C++ 的私有(private)访问说明符?

标签 c++ templates compiler-construction

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

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

它似乎跨过了 C++ 的私有(private)访问说明符。它允许我调用私有(private)函数和读/写私有(private)数据成员。

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

c++ template seems to break access specifiers

所以我很自然地尝试使用那个人的测试代码。有趣的是,我的 gcc 4.5 编译器确实有这个错误(它接受代码并打印私有(private)信息),尽管它在 gcc 4.3 中被报告,而我使用 4.5。

无论如何,我然后去了 Comeau 在线编译器,该线程的一些回复说他们试过了。我确认 Comeau 接受该问题的代码,但它确实接受我下面的代码。

所以最终我的问题是,我是否偶然发现了 GCC 和 Comeau 的 C++ 编译器中的错误?这是否用 VC++ 编译?如果这不是错误,有人可以解释它是如何工作的吗?我知道它能够声明一个静态成员函数指针并将其指向私有(private)部分,但它是如何实现的呢?

杂项说明:是的,我知道实际上这样做是非常非常糟糕的。如果您声明一个成员数据 ptr 并允许您读/写私有(private)数据,这也将起作用。一些奇怪的评论来 self 试图标记它以便理解。这段代码不是我想出来的,我也不认为这是我的功劳。我刚在谷歌上找到它。我可能没有足够的声誉点数来回复评论,但我会阅读您所说的一切。感谢您查看。

#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 修订版 160292] 版权所有 (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;
}

关于c++ - 为什么允许此模板代码违反 C++ 的私有(private)访问说明符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8249191/

相关文章:

compiler-errors - ANTLR4.7 : rule XXX contains a closure with at least one alternative that can match an empty string'

c++ - 传递堆栈对象的所有权而不重复

c++ - C++20 上惯用的 DirectX12 结构初始化中断

c++ - 在 openGL 中加载图像

c++ - 非常基本的模板功能出现问题

scala - SBT:在编译期间查看类文件摘要?

c++ - 从spinbox保存数据

C++ 隐式模板实例化

c++ - 将成对的参数包解压缩为数组和元组

c++ - 在 Xcode 中编译 C++ 时出现很多错误