Скрытие переменных-членов, которые не должны быть видоизменены в базовом классе, который позволяет только константный доступ, чтобы можно было сохранить оператор присваивания - PullRequest
0 голосов
/ 09 мая 2019

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

Итак, мне пришла в голову идея «спрятать» член в базовом классе, который разрешает доступ к const только через геттер:

class Base
{
public:

    Base(Settings settings) : mSettings(settings) {}

    const Settings&
    GetSettings() const { return mSettings; }

private:

    Settings mSettings;
};

class Derived : Base
{
public:

    Derived(Settings settings) : Base(settings) {}
 };

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

Кто-нибудь видит какие-либо проблемы или подводные камни с этим? Есть ли какие-нибудь бэкдор-способы изменить член в любом случае, что сделает всю конструкцию бесполезной?

РЕДАКТИРОВАТЬ: Чтобы дать немного больше контекста о случае использования. Settings для класса Product. Это включает в себя такие вещи, как размеры продукта. Продукт не может изменить свой размер, и я хочу предотвратить случайное изменение, ограничив доступ к настройкам как постоянный. Тем не менее, это нормально для кода клиента, чтобы сделать назначения x = y //Product x now has the same properties as y

1 Ответ

1 голос
/ 09 мая 2019

Технически, вы все еще могли бы написать:

void oops(Settings s) {*dynamic_cast<Base*>(this) = Base(s);}

Но, честно говоря, хороший дизайн программы и хорошие практики программирования идут рядом.Я думаю, что вы достаточно безопасны: если кто-то заходит так далеко, чтобы сломать ваш интерфейс, что-то не так с программистами, которых вы нанимаете.Модификаторы доступа, такие как private и protected, не предназначены для обеспечения безопасности: они здесь, чтобы помочь вам, хорошему разработчику TM , чтобы избежать стрельбы себе по ногеи они делают это, предоставляя компилятору (и вам самим) больше информации о том, кто должен получить доступ к какой-либо информации, чтобы он мог генерировать полезные сообщения об ошибках, предназначенные для предотвращения таких ошибок.

Короче говоря: вы здесь босс, а не компилятор.Четко выражайте свои намерения (как вы уже сделали) и не пытайтесь использовать интерфейсы таким образом, чтобы они явно не предназначались для использования, и у вас все будет хорошо.

...