Почему этот код шаблона разрешен нарушить спецификатор частного доступа C ++?

В следующем коде, который я нашел здесь:

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 не принимает код из этого вопроса, но он принимает мой код, приведенный ниже, .

Итак, в конечном итоге мой вопрос: наткнулся ли я на ошибку в GCC и компиляторе C ++ Comeau? Компилируется ли это с VC ++? Если это не ошибка, может кто-нибудь объяснить, как это работает? Я понимаю, что он может объявить статический указатель на функцию-член и указать его на закрытый раздел, но как он этого добивается?

Разные примечания: Да, я знаю, что на самом деле делать это очень-очень плохо. Это также будет работать, если вы объявите элемент данных ptr и разрешите вам читать / писать в личные данные. Некоторые из странных комментариев были от меня, когда я пытался обозначить это для понимания. Я не придумывал этот код и не беру на себя ответственность за него. Я только что нашел в гугле. У меня может не хватить очков репутации, чтобы отвечать на комментарии, но я прочту все, что вы говорите. Спасибо, что посмотрели.

#include 

using namespace std;


//--------------------------------------------
//
template
struct result 
{
  /* export it ... */
  typedef typename Tag::type type;

  static type ptr;
};


// allocate space for the static member
template
typename result::type result::ptr;

//--------------------------------------------

template
struct rob : result 
{
  /* fill it ... */
  struct filler 
  {
      filler() { result::ptr = p; }
  };

  static filler filler_obj;
};

// allocate space for the static member
template
typename rob::filler rob::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;



int main()
{
    A a;
    (a.*result::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.

7
задан Community 23 May 2017 в 12:27
поделиться