基数 class 指针的成员向量

member vector with base class pointers

我有一个 class,向量如下:

#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 的副本来初始化一个新对象,其指针将为 pushed_back 。如果我不使用 new,我将在 b 和 vector 之间共享资源(这是一个罪过)。

我想保持多态性。我如何确保被推回的对象保持它们在创建期间分配的类型,而不是将所有内容都强制到 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);