2

私は共有ポインタを持つベクトルを持っています:

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

これらのオブジェクトのコピーを含むベクターを返すゲッター関数が必要です。

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

問題は、 Descriptor が抽象クラスであり、それらをベクトルに追加しようとすると、次のように正しく記述されることです。

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

すべてのタイプの派生クラスを試すことでこれを解決できstd::dynamic_pointer_castますが、これを達成するためのより簡単な方法があるはずです。

元のオブジェクトを返されたベクトルにコピーするより良い方法を教えてもらえますか?

4

2 に答える 2

4

Descriptorオブジェクトは抽象的であるため、作成できません。

ただし、これらのオブジェクトへのポインタのディープコピーを作成できます。

これを行うには、クラスDescriptorに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());
    }
}
于 2012-09-20T15:33:24.443 に答える
1

s を使用してオブジェクトを保存しているshared_ptrので、それらは大きなオブジェクトであり、コピーしてはならないか、実際にはコピーしてはならないものの単一のインスタンスを表していると思います。

この場合、呼び出し元がポイント先のオブジェクトを変更するのを防ぐ const ポインターのベクトルを設定するだけの方がよい場合があります。

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);
    }
}
于 2012-09-21T08:06:14.797 に答える