Как сделать объект указателем в константный объект постоянным?

class Foo {
public:
int a = 1;
};

class Bar {
public:
Foo *foo_ptr = new Foo;
};

int main() {
const Bar bar;
bar.foo_ptr.a++;        //   valid: a == 2
bar.foo_ptr = nullptr;  // invalid: foo_ptr is const
}

Я понимаю, почему код выше верен — объект bar постоянно, так foo_ptr постоянный указатель на неконстантный Foo объект. Но я думаю, что это немного нелогично. Зачем Foo объект тоже не стал постоянным?

Что мне делать, если я хочу Bar объект, чтобы стать абсолютным const здесь, и foo_ptr быть постоянным указателем на постоянный объект?

Например, я отправляю Bar возражать против какого-то метода, и я не хочу этого или любой Foo объекты в нем должны быть модифицируемыми.

0

Решение

Но я думаю, что это немного нелогично. Зачем Foo объект тоже не стал const?

Компилятор не может предположить, насколько далеко расширить понятие const, Вы, как дизайнер Bar, должен помочь компилятору в этом. Вы можете сделать это, сделав переменную-член private и предоставление public интерфейсы, которые сохраняют constплотность объекта, на который указывает указатель.

Обновите свой класс:

class Bar {
public:
Foo* getFoo();
Foo const* getFoo() const;

private:
Foo *foo_ptr = new Foo;
};

и сейчас

int main() {

const Bar bar1;
bar1.getFoo()->a++;  // Not OK. Compiler error.

Bar bar2;
bar2.getFoo()->a++;  // OK.
}
3

Другие решения

В вашем случае вы можете использовать значение вместо указателя:

class Bar {
public:
Foo foo;
};

затем bar.foo будет постоянным, когда bar является

Если вам действительно нужен «указатель», вы можете использовать станд :: экспериментальный :: propagate_const

class Bar {
public:
std::experimental::propagate_const<Foo*> foo_ptr = new Foo; // work also with smart pointers
};

демонстрация

1

По вопросам рекламы [email protected]