2017-02-22 43 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())只是一個淺拷貝到執行程序,如果我想要做的深層副本,如何更改代碼?

而且executor是的unique_ptr這點的AbstractQueryExecutor的情況下,AbstractQueryExecutor是具有一些虛函數的基類,所以如果我更改代碼以 executor(new AbstractQueryExecutor(other_qr.executor.get())),它會這樣說:

error: cannot allocate an object of abstract type ‘AbstractQueryExecutor’ 
note: because the following virtual functions are pure within ‘AbstractQueryExecutor’: 
+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

編寫一個value_ptr,它繼承自unique_ptr,但複製構造/分配調用unique_ptr<T> T::clone() const非空T*來克隆。

使用。

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 /分配。

另外,考慮複製寫入而不是深層複製。