class test {
public:
test(int value = 0): x(value) {}
int& get(){
return x;
}
private:
int x;
};
это позволит клиентскому коду мутировать приватные члены
это допустимо в C ++, но почему?
Есть ли ситуации, когда вам нужно было бы нарушить инкапсуляцию класса?
Сделать участника приватным, значит вы не можете получить к нему доступ непосредственно. Но ничто не ограничивает вас в доступе к нему косвенно через публичного участника. Это зависит от вашего дизайна. Вы даже можете сделать это:
class test {
public:
test() : x(y) {}
int &x;
private:
int y;
};
Предположим, что в вашем классе вы хотите подсчитать, сколько раз член читает / пишет. Итак, вы можете сделать это private
затем поместите функцию-член, которая возвращает ссылку на переменную:
class test {
public:
test(int value = 0): x(value), count(0) {}
int& get(){
count++;
return x;
}
private:
int x;
int count;
};
Я надеюсь, что этот пример показывает, как полезно сделать члена закрытым, а затем косвенно доступ к нему.
Прежде всего, давайте рассмотрим реализацию того, что вы описываете. Было бы очень обременительно делать это правильно. Ваш пример достаточно прост. Но что, если ссылка прошла через ряд функций, прежде чем достигла функции, которая ее выставила? Компилятору придется выполнять исключительно сложный статический анализ, выходящий за пределы уровней статического анализа, которые разумно ожидать от авторов компиляторов.
Таким образом, даже если бы дизайнеры хотели запретить это, это было бы непросто. Хотели бы дизайнеры остановить это? Очень сомнительно. Если бы они сделали это, как бы оператор [] был реализован в контейнере или строке?
Есть ли ситуация, когда вам действительно нужно
нарушить инкапсуляцию класса
Как показывает пример оператора [] для контейнеров и строк, эта функция фактически используется для поддержки инкапсуляции.
Зачем? Потому что C ++ в основном пытается позволить вам делать все, что вы хотите, а не мешать вам; это не очень старается, чтобы держать вас в безопасности. Если вы хотите безопасный язык, используйте что-то еще. У вас есть что-то вроде объектной ориентации, если вы хотите, но если вы хотите вырваться из этого, вам предоставляется больше силы. С большой властью приходит большая ответственность.
Ничего не стоит, что вам даже не нужно это нарушать инкапсуляцию; Вы можете просто переинтерпретировать указатель «test» как целое число и получить доступ к приватному полю таким образом.