2013-08-23 16 views
7

fooというクラスが、barというクラスから継承しているとします。std :: unique_ptrをstd :: unique_ptrにスーパークラスに変換する正しい方法は何ですか?

私はstd::unique_ptrのインスタンスをfooに持っていて、それはstd::unique_ptr<bar>という関数に渡したいと思います。自分の関数でポインタを変換するにはどうすればいいですか?

+0

は '多型のインスタンスをfoo'ていますか? – Mahesh

+2

メモリがどこから来たのか、後で何が起こるのかに関わらない関数を作成するには、パラメータを参照(またはヌルの場合は未処理のポインタ)で取る。 –

+1

@NeilKirk:この関数では動作しますが、 'unique_ptr 'をコレクションに格納するのは合理的な使用例です。関数がそれを格納しなければならない場合... –

答えて

27

あなたはstd::unique_ptr<bar>std::unique_ptr<foo>右辺値に変換することができます。

-1

ほとんどの基本的な規則に違反するため、指定したポインタを保持するインスタンスは1つだけで済み、unique_ptrは完全な所有権を持ちます(スコープ外になると、削除されます)。

unique_ptr<T>unique_ptr<U>(ここではU : T)は互換性がありません。

あなたが複数のインスタンスを持つことができたためshared_ptrについては、それがshared_ptrを受け入れることを除いて、ちょうどstatic_castのように動作し、別の1(と同じオブジェクトへの両方のポイント)を返しstd::static_pointer_castがあります。

unique_ptrを絶対に使用する必要がある場合は、まず現在のunique_ptrを無効にしてそのポインタを正しいタイプの新しいポインタに挿入する関数を作成する必要があります。また、関数呼び出しの後に逆の変換を行う必要があるかもしれません。

std::unique_ptr<foo> f(new foo); 
std::unique_ptr<bar> b(std::move(f)); 

明らかに、ポインタがbによって所有され、bbarニーズを破壊してしまった場合virtualデストラクタを持っている:

+1

+1。完全性のために、他の共通のポインタ変換のために 'std :: dynamic_pointer_cast <>'と 'std :: const_pointer_cast <>'が存在します。 – justin

+3

もちろん、明らかに所有権を移譲する必要があります。 @MatthieuM。 –

+0

"もしあなたが絶対にunique_ptrを使う必要があれば、あなたの現在のunique_ptrを無効にし、そのポインタを正しいタイプの新しいポインタに入れる関数を作成する必要があります。私の指摘は、 'unique_ptr 'は 'unique_ptr '参照にバインドできないということでした。まさにそのような所有権を移譲することも、例外的に安全ではありません。 – zneak

0

あなたはこの構文を使用することができます:

std::unique_ptr<parent> parentptr = std::unique_ptr<child>(childptr); 

それともstd::moveを使用することができます。

他のオプションは、生のポインタを発するようになっていますが、機能を変更する必要があります。http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters:ここ

void func(const parent* ptr) 
{ 
    // actions... 
} 
func(*childptr); 

はスマートポインタや関数に渡す程度の良い品です。

2

継承のために特別なものは必要ありません。あなたは、関数にunique_ptrをを渡すためにstd::moveを使用する必要があるが、これは型が一致する場合も同様です:

#include <memory> 

struct A { 
}; 

struct B : A { 
}; 

static void f(std::unique_ptr<A>) 
{ 
} 

int main(int,char**) 
{ 
    std::unique_ptr<B> b_ptr(new B); 
    f(std::move(b_ptr)); 
} 
関連する問題