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
объекты в нем должны быть модифицируемыми.
Но я думаю, что это немного нелогично. Зачем
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.
}
В вашем случае вы можете использовать значение вместо указателя:
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
};