抽象类的shared_ptr向量到副本的向量

vector of shared_ptr of abstract class to vector of copys

本文关键字:向量 副本 shared 抽象类 ptr      更新时间:2023-10-16

我有一个带有共享指针的向量:

std::vector<std::shared_ptr<DescriptorsNs::Descriptor> > mDescriptorList;

现在我想要一个 getter 函数,它返回一个包含这些对象副本的向量:

void CatUpdater::getDescriptorList(std::vector<Descriptor*>& descriptorList) const
{
    descriptorList.clear();
    for (auto it = mDescriptorList.begin(); it != mDescriptorList.end(); it++)
    {
        descriptorList.push_back(*it);
    }
}

现在的问题是描述符是一个抽象类,当我尝试将它们添加到向量中时,它正确地指出:

/usr/include/c++/4.7/ext/new_allocator.h|110|error: cannot allocate an object of abstract type ‘DescriptorsNs::Descriptor’|

我可以通过尝试对所有类型的派生类进行std::dynamic_pointer_cast来解决此问题,但应该有一种更简单的方法来实现这一点。

谁能告诉我将原始对象复制到返回的向量的更好方法?

你不能制作描述符对象,因为它是抽象的。

但是,您可以创建指向这些对象的指针的深层副本。

为此,您的类描述符缺少虚拟方法clone

将其添加到您的类中并在您的派生中正确实现。

class Descriptor {
 ...
  virtual Descriptor* clone() const = 0;
};

class SomeDescriptor : public Descriptor {
 ...
  virtual Descriptor* clone() const { return new SomeDescriptor (*this); }
};

并使用clone(),同时将一个向量深度复制到另一个向量:

void CatUpdater::getDescriptorList(std::vector<std::shared_ptr<DescriptorsNs::Descriptor> >& descriptorList) const
{
    descriptorList.clear();
    descriptorList.reserve(mDescriptorList.size());
    for (auto it = mDescriptorList.begin(); it != mDescriptorList.end(); it++)
    {
        descriptorList.push_back((*it)->clone());
    }
}

我猜当你使用shared_ptr存储你的对象时,它们要么是大对象,不应该被复制,要么它们代表一些东西的单个实例,同样不应该被复制。

在这种情况下,您最好只填充一个常量指针向量,这将阻止调用者修改指向的对象。

typedef std::shared_ptr<const Descriptor> ConstSharedPtr;
void CatUpdater::getDescriptorList(
                    std::vector<ConstSharedPtr>& descriptorList
                    ) const
{
    descriptorList.clear();
    for (auto it = mDescriptorList.begin(); it != mDescriptorList.end(); it++)
    {
        descriptorList.push_back(it);
    }
}