Наверное, у каждого бывали в жизни случаи, когда очень хотелось получить несанкционированный доступ к закрытым членам какого-то класса. Ну вот понимаешь, что нельзя, но очень хочется. А знаете ли вы, что это можно сделать абсолютно легально и в соответствии со стандартом С++? Ну, кто-то знает, а кто-то нет. Фокус в том, что существует один сценарий, когда мы имеем полное право использовать имя закрытого члена класса. Это случай явного инстанцированя какого-нибудь шаблона:
17.7.2 Explicit instantiation12 The usual access checking rules do not apply to names used to specify explicit instantiations.
То есть мы можем обращаться к закрытому члену класса при явном инстанцировании какого-нибудь шаблона, параметром которого является этот член. Таким образом, задача сводится к тому, чтобы, при инстанцированиии шаблона класса, сохранить значение его определенного параметра, имеющего тип указателя на член, в определенную статическую переменную такого же типа. Добавляем синтаксического сахарку и дело, как говорится, в шляпе.
Здравствуйте, Nikе, Вы писали:
_>>Image: 2013_09_10_12_12_allunix_ru_back_screamingrobot.jpg N>А почему бы и нет?
Новый тренд: русские программисты (на манер британских учоных)
Когда им нечем заняться, они придумывают публичный доступ к закрытым данным.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
N>>А почему бы и нет? V>Новый тренд: русские программисты (на манер британских учоных) V>Когда им нечем заняться, они придумывают публичный доступ к закрытым данным.
Russian hackers, sir.
И каждый день — без права на ошибку...
Re: [Trick] Легальный способ доступа к закрытым членам
Хотелось бы тут выводить типы A и int автоматически.
R>ENABLE_PIVATE_MEMBER_ACCESS(A_value, A, int, m_value)
Использование decltype в специализации компилируется, но любые попытки использовать дальше не увенчались успехом.
Есть идеи ?
template<typename MemberPtrT, MemberPtrT>
struct X;
template<> struct X<decltype(&A::m_value), &A::m_value> // : Base<decltype(&A::m_value)> // нет доступа
{
// using Q = decltype(&A::m_value); // нет доступа
};
_NN>Использование decltype в специализации компилируется, но любые попытки использовать дальше не увенчались успехом. _NN>Есть идеи ?
Убил на это уйму времени, результат — ноль
Я пробовал обеспечить доступ через дружественные фунции. На msvc работает, на gcc — нет. Причем, gcc прав
P.S. Кстати, если бы это удалось сделать, то одновремено с этим получилось бы сделать указатель на член constexpr, а не защелкивать его в runtime переменной, как сейчас.
Здравствуйте, rg45, Вы писали:
R>Я пробовал обеспечить доступ через дружественные фунции. На msvc работает, на gcc — нет. Причем, gcc прав
Где код ?
Может получиться что-нибудь придумать.
R>P.S. Кстати, если бы это удалось сделать, то одновремено с этим получилось бы сделать указатель на член constexpr, а не защелкивать его в runtime переменной, как сейчас.
Здравствуйте, _NN_, Вы писали:
R>>Я пробовал обеспечить доступ через дружественные фунции. На msvc работает, на gcc — нет. Причем, gcc прав
_NN>Где код ? _NN>Может получиться что-нибудь придумать.
Не сохранился, восстановлю, как появится свободная минутка. Идея основывается на том, что в некоторых случаях ADL заглядывает внутрь классов в поисках дружественных функций. Только по стандарту, это делается только в том случае, если в сигнатуре функции присутствует какая-то связь с классом, дружественной которому эта функция является. gcc постуает строго, как написано в стандарде. А msvc более "либеральна" в этом плане. Таким образом нужный указатель на член можно запаковать в тип возвращаемого значения, а потом вытащить его при помощи внешней метафункции.
--
Re: [Trick] Легальный способ доступа к закрытым членам
Здравствуйте, rg45, Вы писали:
R>Наверное, у каждого бывали в жизни случаи, когда очень хотелось получить несанкционированный доступ к закрытым членам какого-то класса.
Поэтому я по возможности предпочитаю такие приватные поля.
// Public.hstruct Public {
static Public* create(int value);
virtual int getValue() const=0;
virtual ~Public() {}
};
// Public_create.cpp#include"public.h"#include"a_lot_of_trash_and_other_dependencies"struct Private : Public {
int value;
Private(int value) : value(value) {}
int getValue() const { return value; }
};
Public* Public::create(int value) {
return new Private(value);
}
Уменьшается время компиляции и связность, улучшается читаемость и не хочеться несанкционированного доступа
А то что в C++ называется private ниразу не private оно не скрывает реализации просто осложняет доступ.
Зато тянет за собой зависимости связанные с типом приватного поля и его реализацией, чего в большинстве случаев нафиг не упало.
Re[2]: [Trick] Легальный способ доступа к закрытым членам
Здравствуйте, kov_serg, Вы писали:
_>Поэтому я по возможности предпочитаю такие приватные поля. _>Уменьшается время компиляции и связность, улучшается читаемость и не хочеться несанкционированного доступа _>А то что в C++ называется private ниразу не private оно не скрывает реализации просто осложняет доступ. _>Зато тянет за собой зависимости связанные с типом приватного поля и его реализацией, чего в большинстве случаев нафиг не упало.
Я, в общем-то, имею кое-какое представление и о способах сокрытия реализации, и об абстракных классах, их преимуществах и областях применимости. Я только не очень понимаю, зачем ты здесь обо всем этом рассказываешь. Вопрос, по-моему, был поставлен предельно ясно: "кто хочет вишенку, вот вам вишенка". Кто не хочет, тот не ест. Ты же, зачем-то, пытаешься убедить всех, что хотеть вишенку — это плохо, потому, что на Луне вишни не растут
Здравствуйте, rg45, Вы писали:
R>Я, в общем-то, имею кое-какое представление и о способах сокрытия реализации, и об абстракных классах, их преимуществах и областях применимости. Я только не очень понимаю, зачем ты здесь обо всем этом рассказываешь. Вопрос, по-моему, был поставлен предельно ясно: "кто хочет вишенку, вот вам вишенка". Кто не хочет, тот не ест. Ты же, зачем-то, пытаешься убедить всех, что хотеть вишенку — это плохо, потому, что на Луне вишни не растут
Просто так, не обижайся. Я знаю что у вас черный пояс по C++, но нафига такие вишни? Как вообще пришла в голову идея лезть туда где написано не лезь убъёт?
И что мешало просто вместо private просто написать public или define-ом (#define RELEASE_PRIVATE public) это сделать.
Более того что сечас легальный способ в новом стандарте может перейти в разряд UB, что бы не было скучно.
Re[2]: [Trick] Легальный способ доступа к закрытым членам
Здравствуйте, _NN_, Вы писали:
_NN>Использование decltype в специализации компилируется, но любые попытки использовать дальше не увенчались успехом. _NN>Есть идеи ?
_NN>
_NN>template<typename MemberPtrT, MemberPtrT>
_NN>struct X;
_NN>template<> struct X<decltype(&A::m_value), &A::m_value> // : Base<decltype(&A::m_value)> // нет доступа
_NN>{
_NN> // using Q = decltype(&A::m_value); // нет доступа
_NN>};
_NN>
_NN>Где код ? _NN>Может получиться что-нибудь придумать.
Вот, восстановил, все-таки. Это работает на mcvc, но не работает на gcc. Ключевой момент в том, что по стандарту хелперная функция не должна в этом случае вноситься в область видимости пространства имен. Но вот на msvc вносится. Э-х-х! сколько клевых фишек можно было бы сделать, будь это стандартым поведением! Синтаксическим сахаром на этор раз не стал особо заморачиваться, ибо все равно не портабельно: