vector von abstrakter Klasse - wie implementieren?
-
Ich hab eine abstrakte Klasse X und eine weitere Klasse Y, die einen std::vector mit Instanzen von X besitzt. Darüber hinaus, soll es in Y eine Methode, um weitere Instanzen zu X hinzuzufügen.
Mein bisheriger Ansatz war:
class Y { public: std::vector<std::unique_ptr<X>> v; void add(X* obj) { v.emplace_back(obj); } }
Ich finde den Ansatz nicht so gut, weil sowas wie
Y y; y.add(new X_subclass());
so aussieht, als hätte man vielleicht ein delete vergessen.
Gibt es bessere Möglichkeiten, mein Vorhaben zu implementieren?
-
#include <vector> #include <memory> #include <utility> class X { public: virtual ~X() {} }; class X_subclass : public X {}; class Y { std::vector<std::unique_ptr<X>> v; public: void add(X* obj) { v.emplace_back(obj); } void add(std::unique_ptr<X> obj) { v.emplace_back(std::move(obj)); } template <typename T, typename ...Args> void add(Args&& ...args) { v.emplace_back(std::unique_ptr<T>(new T(std::forward<Args>(args)...))); } }; int main() { Y y; y.add(new X_subclass()); y.add(std::unique_ptr<X>(new X_subclass())); y.add(std::make_unique<X_subclass>()); // mit C++14 oder selbstgemachtem make_unique<..>(..) y.add<X_subclass>(); }
// edit
Beispiel vervollständigt und Variante mit Variadic-Templates hinzugefügt. Der Ansatz mit Variadic-Templates entspricht im Wesentlichen einem selbstgemachten und versteckten std::make_unique<..>(..).// edit1
Formatierung bereinigt// edit2
Bei std::forward<..> das fehlende Template-Argument ergänzt