Как можно изменить объекты-члены во время выполнения в композиции?

От Мышление в C ++ Vol. 1 (Р-33):

Композиция имеет большую гибкость. Член
объекты вашего нового класса обычно являются частными, что делает их
недоступен клиентским программистам, использующим класс. это
позволяет изменить эти элементы, не нарушая существующие
код клиента
Вы также можете изменить объекты-члены во время выполнения, чтобы
динамически изменять поведение вашей программы. Наследование,
который описан ниже, не обладает такой гибкостью, поскольку
компилятор должен наложить ограничения во время компиляции на созданные классы
с наследством.

Как мы можем изменить объекты-члены во время выполнения в составе?
Разве объекты не включены при написании объявления класса?

class car
{
private:
engine obj;
}

Итак, вот класс car содержит объект класса engine, Как мы можем изменить это во время выполнения?

Или я что-то упустил?

3

Решение

Попробуйте вместо этого использовать указатель на ваш объект-член:

class car {
engine *obj;
}

Теперь вы можете выбрать во время выполнения, использовать ли экземпляр rotary_engine или же v8_engine или же flux_capacitor_engine,

Конечно, вы можете использовать что-то вроде unique_ptr или shared_ptr управлять владением и временем жизни объекта-члена.

6

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

Это действительно немного расплывчатое утверждение.

Композиция определяет has-a отношения, т.е. car имеет engine. Вы можете заменить двигатель вашего автомобиля, и автомобиль все равно останется автомобилем.

Наследование определяет is-a отношения, т. е. если бы вы определили автомобиль как наследство от двигателя, это означало бы car является engine. Замена двигателя будет означать изменение самого типа автомобиля — если вы измените базовый класс, он автоматически изменит производный класс. Это ограничение не существует при использовании композиции.

Таким образом, в вашем примере композиция является правильным способом.

1

Для чистого состава также возможны изменения времени выполнения:

class Car {
private:
CarPart &get_part(int i) const {
switch(i) {
case 0: return e;
case 1: return w1;
case 2: return w2;
case 3: return w3;
case 4: return w4;
}
}
private:
Engine e;
Wheel w1, w2, w3, w4;
};

Тогда, например, установить свойства легко:

void set_property(int id, std::string name, int value) {
CarPart &p = get_part(id);
p.set(name, value);
}

Это настолько динамично, насколько вы можете получить …

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