Могу ли я получить доступ к закрытым членам вне класса, не используя друзей? - PullRequest
62 голосов
/ 08 января 2009

Отказ

Да, я полностью осознаю, что то, о чем я спрашиваю, совершенно глупо, и что любой, кто хотел бы попробовать такое в рабочем коде, должен быть уволен и / или застрелен. В основном я смотрю, можно ли сделать .

Теперь, когда это не так, есть ли способ получить доступ к закрытым членам класса в C ++ извне класса? Например, есть ли способ сделать это со смещением указателя?

(приветствуются наивные и не готовые к производству техники)

Обновление

Как отмечалось в комментариях, я задал этот вопрос, потому что хотел написать пост в блоге о чрезмерной инкапсуляции (и как это влияет на TDD). Я хотел посмотреть, есть ли способ сказать: «Использование частных переменных не является на 100% надежным способом обеспечения инкапсуляции, даже в C ++». В конце я решил больше сосредоточиться на том, как решить проблему, а не на том, почему это проблема, поэтому я не представил некоторые материалы, поднятые здесь, так заметно, как планировал, но я все же оставил ссылку.

Во всяком случае, если кому-то интересно, как это получилось, вот оно: Враги тест-ориентированной разработки, часть I: инкапсуляция (предлагаю прочитать, прежде чем вы решите, что я сумасшедший).

Ответы [ 24 ]

0 голосов
/ 08 января 2009

просто создайте свою собственную функцию-член доступа для расширения класса.

0 голосов
/ 23 декабря 2010

"использование закрытых переменных не является 100% надежным способом принудительной инкапсуляции, даже в C ++." В самом деле? Вы можете разобрать нужную вам библиотеку, найти все необходимые смещения и использовать их. Это даст вам возможность изменить любого частного участника, которого вы любите ... НО! Вы не можете получить доступ к частным пользователям без грязного взлома. Допустим, что запись const не сделает вашу константу действительно постоянной, потому что вы можете отбросьте const или используйте его адрес, чтобы сделать его недействительным. Если вы используете MSVC ++ и указали компоновщику "-merge: .rdata = .data", трюк будет работать без ошибок доступа к памяти. Можно даже сказать, что написание приложений на C ++ не является надежным способом написания программ, потому что результирующий низкоуровневый код может быть исправлен откуда-то извне, когда ваше приложение работает. Тогда каков надежный документированный способ обеспечения инкапсуляции? Можем ли мы спрятать данные где-нибудь в оперативной памяти и запретить доступ к ним ничего, кроме нашего кода? Единственная идея, которая у меня есть, - это зашифровать частных участников и сделать их резервную копию, потому что что-то может повредить этих участников. Извините, если мой ответ слишком груб, я не хотел никого обидеть, но я действительно не думаю, что это утверждение является мудрым.

0 голосов
/ 08 января 2009

Для всех людей, предлагающих " # определить частную публичную ":

Такие вещи незаконны . Стандарт запрещает определять / отменять определение макросов, которые лексически эквивалентны зарезервированным ключевым словам языка. Хотя ваш компилятор, вероятно, не будет жаловаться (я еще не видел компилятор, который это делает), это не то, что нужно делать «Хорошо».

0 голосов
/ 30 июня 2010

поскольку у вас есть объект требуемого класса, я предполагаю, что у вас есть объявление класса. Теперь вы можете объявить другой класс с теми же членами, но оставить все описатели доступа общедоступными.

Например, предыдущий класс:

class Iamcompprivate
{
private:
    Type1 privateelement1;
    Typ2 privateelement2;
    ...

public:
    somefunctions
}

вы можете объявить класс как

class NowIampublic
{
**public:**
    Type1 privateelement1;
    Type2 privateelement2;
    ...

    somefunctions
};

Теперь все, что вам нужно сделать, это привести указатель класса Iamcompprivate в указатель класса NowIampublic и использовать их по своему усмотрению.

Пример:

NowIampublic * changetopublic(Iamcompprivate *A)
{
    NowIampublic * B = (NowIampublic *)A;
    return B;
}
...