В основном это типичный случай неправильного использования наследования. Ракета и Корабль вообще не должны наследоваться от ObjectManager. Вы должны зарезервировать наследование, когда у вас есть «своего рода» отношения между объектами (например, «Ядерная ракета» - это разновидность ракеты).
Здесь вы используете наследование для его «механических» свойств (автоматическая регистрация новых экземпляров), но для достижения той же цели было бы так же легко создавать объекты, говорит Ракета, из некоторого общего класса ManagedObject и заставлять его добавлять новые экземпляры некоторых уникальных глобальных объектов, управляющих списком экземпляров (или делайте это без наследования, переопределяя значения по умолчанию new и delete для Missiles). Либо вы можете передать менеджера в класс Missile в качестве параметра экземпляра, либо создать Missiles через какой-либо метод конструктора менеджера, который добавит его в контейнер.
Все эти решения работают и являются более удовлетворительными, чем ваш оригинальный код (который также работает), и могут быть другие, о которых я не думал. Все же ни одно из вышеупомянутых предложений не является полностью удовлетворительным для меня. Основная проблема заключается в том, что в C ++ отсутствует надлежащий механизм метакласса (C ++ - это эффективность времени компиляции, но не гибкость).
Подумав о различных возможностях, я пришел к следующему коду. Пример только для корабля и не связывается с ракетой или использованием общего кода для обоих классов через шаблон (даже если это достаточно просто). Мой ответ сфокусирован на ведении актуального списка всех экземпляров Корабля, существующих в системе в данный момент времени, без вмешательства в наследство. Я выбрал это решение, потому что считаю, что оно более KISS (Keep It Stupid and Simple), а сложные решения - настоящее бремя, когда вам приходится поддерживать свой код. Идея также состоит в том, чтобы избежать перекодирования чего-то, что уже существует в STL, например, for_each.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<class Ship*> all_ships;
class Ship
{
public:
Ship(void){
cout << "Construct Ship at " << this << endl;
all_ships.push_back(this);
}
~Ship(void){
cout << "Destroy Ship at " << this << std::endl;
// we remove it from the list
int i = 0;
while (all_ships[i] != this) { i++; }
all_ships[i] = all_ships.back();
all_ships.pop_back();
}
static void show(Ship *s){
cout << "ship :" << s << "\n";
}
};
void list_all_ships(){
cout << "List of Ships\n";
for_each(all_ships.begin(), all_ships.end(), Ship::show);
cout << "\n";
}
int main(void)
{
cout << "Two automatic (on stack) Ships\n";
Ship s1;
Ship s2;
list_all_ships();
cout << "One new dynamic (on heap) Ship\n";
Ship * s3 = new Ship();
list_all_ships();
cout << "Delete dynamic Ship\n";
delete s3;
list_all_ships();
cout << "The two dynamic Ships will be deleted when getting out of Scope\n";
return 0;
}