Я не думаю, что код делает то, что вы думаете, что он делает. Я добавил конструкторы по умолчанию и назначил / операторы для вашего класса Foo с некоторыми регистрациями, чтобы увидеть, что происходит. Эти конструкторы автоматически добавляются компиляторами, если вы не отключите их явно. Смотрите вывод здесь .
Что происходит в
f = {20};
, так это то, что вы создаете другой объект Foo, а затем перемещаете и присваиваете его исходному экземпляру.
В этом случае это эквивалентно
f.a = 20; // Assuming we make a public.
В заключение. Если вы используете только для изменения полей в существующем экземпляре (в данном случае через операторы присваивания). Тогда все должно работать нормально. Это не обязательно лишает законной силы принципы OOP, если только у вас нет предположений, что Bar.foo является постоянным или не изменяется. Обычно это называется композицией, и она довольно распространена (ваш пользовательский интерфейс будет содержать различные экземпляры кнопок, которые могут быть изменены из других источников).
Если вы ожидаете изменить реализацию (скажем, Foo - это виртуальный класс, и вы хотите другой вывод, который нужно заменить), тогда в вашем коде вам понадобится Foo* f = new Foo(10);
. У вас будет копия указателя в b
, и назначение создаст новый класс, который не будет обновляться в b
(что-то вроде f = new FooDerived(20);
.
. Чтобы он работал, вам нужен провайдер класс (это шаблон OOP). Это будет то, что даст вам Foo
. Самый простой будет Foo**
. Но, вероятно, лучше иметь что-то более настраиваемое.
Тем не менее, для любой серьезной работы старайтесь держаться подальше от голых указателей (Foo*
). Используйте unique_ptr или shared_ptr в зависимости от ситуации, чтобы избежать множества проблем в будущем.