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


Log in to reply