Как элегантно нарезать объект
Так что в основном у меня есть класс SomethingSwimming
и производный класс Ship
, Я хочу реализовать это на каком-то событии Ship
может потерять свои особые качества (например, держать в заложниках омаров) и стать просто еще одним SomethingSwimming
объект.
Проиллюстрировать:
class SomethingSwimming
{
protected:
int m_treasures;
public:
SomethingSwimming(int treasures): m_treasures(treasures) {;}
virtual int howManyLobstersOnBoard() {return 0; }
};
class Ship: public SomethingSwimming
{
protected:
int m_lobstersOnBoard;
public:
Ship(int treasures, int lobstersOnBoard): SomethingSwimming(treasures), m_lobstersOnBoard(lobstersOnBoard) {;}
int howManyLobstersOnBoard() {return m_lobstersOnBoard; }
};
void crash(shared_ptr<SomethingSwimming>& b)
{
b = make_shared<SomethingSwimming>(100);
}
int main()
{
shared_ptr<SomethingSwimming> a = make_shared<Ship>(100, 12);
cout << "How many lobsters on board: " << a->howManyLobstersOnBoard() << endl;
crash(a);
cout << "How many lobsters on board: " << a->howManyLobstersOnBoard() << endl;
return 0;
}
Мой вопрос как crash
Ship
так становится только SomethingSwimming
(так что это не Ship
больше) без повторной инициализации.
1 ответ
Нет способа срезать остальную часть объекта, сохраняя идентичность базового субобъекта. Вы можете сделать новую копию базового подобъекта и выбросить производный объект.
В настоящее время вы создаете несвязанный объект в crash
и таким образом m_treasures
не будут затронуты m_treasures
ранее указанного объекта. Чтобы создать копию исходного базового подобъекта, вы можете сделать:
b = make_shared<SomethingSwimming>(*b);
В качестве альтернативы, на сайте вызова вы можете обрабатывать косвенно ссылающуюся базу, как если бы она не была частью производного объекта, статически вызывая виртуальные функции-члены:
a->SomethingSwimming::howManyLobstersOnBoard()
Это приведет к значению m_treasures
независимо от наиболее производного типа объекта.