1

私は次のような構造と関数を手に入れました:

struct MYOVERLAPPED : public OVERLAPPED
{
    //...
};


void func1(std::unique_ptr<MYOVERLAPPED> pBuf)
{
    //...
};

func1-functionに渡したいMYOVERLAPPEDへのポインターを取得しています。私が遭遇する問題は、何を試しても次のエラーが発生することです。

私がすでに試したことは次のとおりです:Try1:

std::unique_ptr<OVERLAPPED> pOver(//....)
HandleAcceptIndication(std::move(pOver));

エラー:エラー1エラーC2440:「初期化中」:「_OVERLAPPED**」から「MYOVERLAPPED*」に変換できません

Try2:

HandleAcceptIndication(new ACCEPT_OVERLAPPED);

エラー1エラーC2664:'HandleAcceptIndication':パラメータ1を'MYOVERLAPPED*'から'std :: unique_ptr<_Ty>'に変換できません

OVERLAPPEDからMYOVERLAPPEDへのこのキャストされたポインターを関数に渡す方法と、何気なく使用しているのにTry2も機能しない理由を誰もが知ってstd::unique_ptr<MYOVERLAPPED> pO(new MYOVERLAPPED) います...?

4

3 に答える 3

11

std::unique_ptr<base>から直接に変換することはできませんが、安全なstd::unique_ptr<derived>キャスト関数を作成することはそれほど難しくありません(つまり、どのような状況でもリソースをリークせず、キャストが有効な場合にのみ成功します。

template <typename Dst, typename Src>
std::unique_ptr<Dst> unique_dynamic_cast( std::unique_ptr<Src>& ptr ) {
    Src * p = ptr.release();                             // [1]
    std::unique_ptr<Dst> r( dynamic_cast<Dst*>(p) );     // [2]
    if ( !r ) {
        ptr.reset( p );                                  // [3]
    }
    return r;                                            // [4]
}

基本的な考え方は、からポインタを抽出しstd::unique_ptr、[1]に取っておかなければならないということです。dynamic_castそれが失敗したかのように直接試すことはできずptr、所有権が解放され、メモリがリークされます。次にdynamic_cast、ローカルポインタから要求されたタイプのポインタへの[2]を実行し、r結果の一意のポインタに所有権を渡します。dynamic_cast失敗した場合はrnullになり、メモリの所有権を元の[3]に戻して、std::unique_ptrコードを呼び出してそれをどう処理するかを決定する必要があります。次に、変換さ std::unique_ptrれたものを[4]の呼び出し元に返します。

于 2011-09-09T16:30:54.420 に答える
2

継承階層で間違った方法をキャストしようとしているため、これは機能しません。Base*からDerived*に暗黙的に変換しようとしています。

于 2011-09-09T15:23:14.287 に答える
0

unique_ptr<A>unique_ptr<B>は無関係のタイプです。A*B*(UncleBensに感謝)の間に暗黙の変換が存在しない限り、それらの間で変換することはできません。これは、この場合は当てはまりません。また、キャスト先のサブクラスではないインスタンスを使用して継承階層をキャストダウンしないでください。この場合、はではないため、無効なキャストであるOVERLAPPEDにをキャストしようとしています。そのため、そもそもタイプ間で変換することはできません。MYOVERLAPPEDOVERLAPPEDMYOVERLAPPEDunique_ptr

にを渡そうとしているだけの場合は、次のunique_ptrようfunc1に実行できます。

func1(shared_ptr<MYOVERLAPPED>(new MYOVERLAPPED));

また、関数にaを渡すことによりunique_ptr、元の関数のポインタがNULLに設定されます。を一時として作成して関数に渡すのではなく、後で同じインスタンスを使用する必要がある場合は、参照またはshared_ptrsの使用を検討してください。unique_ptr

于 2011-09-09T15:24:45.500 に答える