2017-02-22 4 views
0

問題は次のとおりです。基本クラスを指すunique_ptrのディープクローンと、基本クラスにいくつかの仮想関数があります。ディープクローンで基本クラスを指すunique_ptr

詳細コード:私は深いコピーをしたい場合は、コピーコンストラクタで

class QueryRewrite { 
public: 
    QueryRewrite(bool wasRes, ReturnMeta rmeta, const KillZone &kill_zone, 
        AbstractQueryExecutor *const executor) 
     : rmeta(rmeta), kill_zone(kill_zone), 
      executor(std::unique_ptr<AbstractQueryExecutor>(executor)) {} 
    QueryRewrite(const QueryRewrite &other_qr) 
     : rmeta(other_qr.rmeta), kill_zone(other_qr.kill_zone), 
      executor(other_qr.executor.get()) {} 
    QueryRewrite(){} 
    QueryRewrite(QueryRewrite &&other_qr) : rmeta(other_qr.rmeta), 
      executor(std::move(other_qr.executor)) {} 
    const ReturnMeta rmeta; 
    const KillZone kill_zone; 
    std::unique_ptr<AbstractQueryExecutor> executor; 
}; 

QueryRewrite(const QueryRewrite &other_qr) 
     : rmeta(other_qr.rmeta), kill_zone(other_qr.kill_zone), 
      executor(other_qr.executor.get()) {} 

executor(other_qr.executor.get())は、コードを変更する方法を、エグゼキュータにちょうど浅いコピーです?

error: cannot allocate an object of abstract type ‘AbstractQueryExecutor’ 
note: because the following virtual functions are pure within ‘AbstractQueryExecutor’: 

そしてexecutorAbstractQueryExecutorは、いくつかの仮想関数を持つ基本クラスですので、私は executor(new AbstractQueryExecutor(other_qr.executor.get()))にコードを変更した場合、それはのようなものを言うだろうAbstractQueryExecutorのインスタンスをポイントし、unique_ptrをあります

+3

Cが 'unique_ptr'を導入し、それらを動作させるために必要なすべての基盤を導入しました!クール! – StoryTeller

+0

http://stackoverflow.com/questions/16030081/copy-constructor-for-a-class-with-unique-ptr – Rishi

+3

'unique_ptr'は本当に問題に関連していません。これは多相コピーの古典的な問題であり、通常は仮想 'clone()'メンバ関数によって解決されます。 – Angew

答えて

0

unique_ptrから継承しますが、コピー構成/割り当てでは、unique_ptr<T> T::clone() constがnullでない場合はT*を呼び出して複製してください。value_ptr

これを使用します。

template<class T, class D=std::default_delete<T>> 
struct value_ptr:std::unique_ptr<T,D>{ 
    using base=std::unique_ptr<T,D>; 
    using base::base; 
    value_ptr()=default; 
    value_ptr(value_ptr&&)=default; 
    value_ptr& operator=(value_ptr&&)=default; 
    value_ptr(base&& o):base(std::move(o)){} 
    value_ptr(value_ptr const&o): 
    value_ptr(o?value_ptr(o->clone()):value_ptr()) 
    {} 
    value_ptr& operator=(value_ptr const&o){ 
    value_ptr tmp(o); 
    *this=std::move(tmp); 
    return *this; 
    } 
}; 

これでいいはずです。コードはテストされていません。

抽象基盤には、virtual std::unique_ptr<AbstractBase> clone()constが追加されていなければなりません。上記のために抽象基盤を実装する必要があります。

また、ゼロのルールに従ってください。値ptrを取得したら、=defaultにすることもできます。また、囲むクラスのコピー/移動のctors/assignをスキップすることもできます。

ディープコピーではなくコピーオンライトを考慮してください。

関連する問題