繁体   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