簡體   English   中英

帶有基類指針的成員向量

[英]member vector with base class pointers

我有一個帶有向量的類,如下所示:

#include <vector>

class Base{};

class Derived: public Base{};

class Foo{
   private:
        std::vector<Base*> vec;
   public:
        Foo() = default;
        void addObject(const Base* b){
        // vec.push_back(new Base(*b));
        // vec.push_back(new Derived(*b));
        }
};

int main(){
        Derived* d = new Derived();
        Base* b = new Base();
        Foo f;
        f.addObject(d);
        f.addObject(b);
        
        delete d;
        delete b;
        return 0;
}

函數addBase可以接收Derived 的指針 該行vec.push_back(new Base(b)); 預計使用 b 的副本來初始化一個新對象,其指針將被push_back 如果我不使用 new,我將在 b 和向量之間共享資源(這是一種罪過)。

我想保持多態性。 我如何確保被推回的對象保持它們在創建過程中分配的類型,而不會將所有內容強制轉換為 Base 對象。

如果要創建傳遞給addObject的對象的克隆,則基本上有兩種選擇。 1) 在BaseDerived有一個虛函數clone ,或者更好 2) 讓復制構造函數處理它。

如果你選擇第二個選項, addObject需要知道傳遞對象的實際類型。 這可以通過模板來完成:

template <class T>
void addObject(const T * t)
{
  Base *b = new T(*t);
}

在健壯的程序中,我們不想使用new / delete而是使用std::unique_ptrstd::shared_ptr t作為引用傳遞,而不是指針,也被認為是更好的做法。

#include <vector>
#include <memory>
#include <iostream>


class Base
{
public:
  virtual void cname() { std::cout << "Base" << std::endl;}
};


class Derived: public Base
{
public:
  virtual void cname() { std::cout << "Derived" << std::endl;}
};
 

class Foo
{
private:
  // You may switch to `std::shared_ptr` if that better fits your use case
  std::vector<std::unique_ptr<Base> > vec;
public:
  template <class T>
  void addObject(const T & t)
  {
    vec.push_back(std::make_unique<T> (t)); 
  }

  void dump()
  {
    for (auto &bp: vec)
      bp->cname();
  }
};

int main(){
  Derived d;
  Base b;

  Foo f;
  f.addObject(d);
  f.addObject(b);

  f.dump();
  
  return 0;
}

自然地,要使其工作,傳遞給addObject的引用必須是正確的類型。 這將創建一個Base類型的克隆,而不是Derived

Derived d;
Base &e = d;
f.addObject(e);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM