Информация об изменениях

Сообщение [Trick] Легальный способ доступа к закрытым членам от 25.09.2018 14:32

Изменено 25.09.2018 14:49 rg45

[Trick] Легальный способ доступа к закрытым членам
Наверное, у каждого бывали в жизни случаи, когда очень хотелось получить несанкционированный доступ к закрытым членам какого-то класса. Ну вот понимаешь, что нельзя, но очень хочется. А знаете ли вы, что это можно сделать абсолютно легально и в соответствии со стандартом С++? Ну, кто-то знает, а кто-то нет. Фокус в том, что существует один сценарий, когда мы имеем полное право использовать имя закрытого члена класса. Это случай явного инстанцированя какого-нибудь шаблона:

17.7.2 Explicit instantiation
12 The usual access checking rules do not apply to names used to specify explicit instantiations.


То есть мы можем обращаться к закрытому члену класса при явном инстанцировании какого-нибудь шаблона параметром которого является этот член. Дальше дело техники. Добавляем синтаксического сахарку и дело, как говорится, в шляпе.

Эскизный пример реализации и использования здесь:

https://ideone.com/meuOaW

Использование выглядит примерно так:

class A
{
public:
 
   explicit A(int value) : m_value(value) { }
 
   int GetValue() const { return m_value; }
 
private:
   int m_value;
};
 
ENABLE_PIVATE_MEMBER_ACCESS(A_value, A, int, m_value)
 
int main()
{
   A a(1);
   std::cout << "a.GetValue(): " << a.GetValue() << std::endl;
   *PrivateMemberAccessor<A_value>(a) = 42;
   std::cout << "a.GetValue(): " << a.GetValue() << std::endl;
}
[Trick] Легальный способ доступа к закрытым членам
Наверное, у каждого бывали в жизни случаи, когда очень хотелось получить несанкционированный доступ к закрытым членам какого-то класса. Ну вот понимаешь, что нельзя, но очень хочется. А знаете ли вы, что это можно сделать абсолютно легально и в соответствии со стандартом С++? Ну, кто-то знает, а кто-то нет. Фокус в том, что существует один сценарий, когда мы имеем полное право использовать имя закрытого члена класса. Это случай явного инстанцированя какого-нибудь шаблона:

17.7.2 Explicit instantiation
12 The usual access checking rules do not apply to names used to specify explicit instantiations.


То есть мы можем обращаться к закрытому члену класса при явном инстанцировании какого-нибудь шаблона, параметром которого является этот член. Таким образом, задача сводится к тому, чтобы, при инстанцированиии шаблона класса, сохранить значение его определенного параметра, имеющего тип указателя на член, в определенную статическую переменную такого же типа. Добавляем синтаксического сахарку и дело, как говорится, в шляпе.

Эскизный пример реализации и использования здесь:

https://ideone.com/meuOaW

Использование выглядит примерно так:

class A
{
public:
 
   explicit A(int value) : m_value(value) { }
 
   int GetValue() const { return m_value; }
 
private:
   int m_value;
};
 
ENABLE_PIVATE_MEMBER_ACCESS(A_value, A, int, m_value)
 
int main()
{
   A a(1);
   std::cout << "a.GetValue(): " << a.GetValue() << std::endl;
   *PrivateMemberAccessor<A_value>(a) = 42;
   std::cout << "a.GetValue(): " << a.GetValue() << std::endl;
}