2016-10-13 17 views
3

cpp referenceshared_from_thisとprivate継承

class Good : std::enable_shared_from_this<Good> 
{ 
    public: std::shared_ptr<Good> getptr() { return shared_from_this(); } 
}; 

... 

auto good = std::make_shared<Good>(); 
good->getptr(); 

しかし、これは、Visual Studioで動作しません(微調整)std::enable_shared_from_thisを使用する方法のこの例を持っている2015(エンタープライズ、バージョン14.0.25123.00アップデート2)、すなわちstd::bad_weak_ptr例外がスローされます。

は(cpp referenceまたはMicrosoftは異なるものも含めて)他の例を見ると、私は、彼らが代わりにprivate 1のpublic継承を使用することに気づきました。 public継承を使用すると、実際には私の問題が解決されます(std::bad_weak_ptrはなくなりましたが、代わりに有効なshared_ptr)。

Cppの参考文献には、std::enable_shared_from_thisから公に継承しなければならないと言われていないので、どこにエラーがありますか? Visual Studioの動作が間違っていますか(private継承を使用しているときに可視性の問題があると思われます)、またはこの制限についてcppの参照に失敗しましたか?

PS:make_shared<good>()またはshared_ptr<Good>(new Good)は違いがありません。

PSS:どちらのバージョンもうまくコンパイルされますが、私的なものだけではうまく動作せず、これは非常に厄介な種類のバグです。

編集:structからclassに変更されました。その例ではCpp参照は実際に公開の継承を使用しています。 まだパブリックでなければならないという言葉はありません。それは実際にそこに記載されている、私は慎重に読むことを学ばなければならない。ありがとう@Angew。

+0

可能な重複します(http:// stackoverflowの.com/questions/27697973/shared-from-this-causing-bad-weak-ptr) –

+0

@πάνταῥεother他の質問には根本的な原因がありません –

+0

@PiotrSkotnicki私はそれを打つことはできませんでした。 –

答えて

2

std::enable_shared_from_thisの典型的な実装は、std::enable_shared_from_this塩基の存在を検出することができるように(あなたのケースでstd::make_sharedによって呼び出さ)std::shared_ptrコンストラクタを必要とするので、そのベースのstd::weak_ptrメンバを設定することができます。 private継承して

、それは不可能ですので、あなたは(std::shared_ptrコンストラクタがstd::enable_shared_from_thisベースを検出することができなかったので、std::weak_ptrは、設定されていなかったので)shared_from_thisを呼び出すときにあなたが得た実行時例外を取得します。

C++標準は言及ような実装:可能な実装を以下に示す:

[ノートの存在を検出することができるユニークなポインタを作成

template<class T> class enable_shared_from_this { 
private: 
    weak_ptr<T> __weak_this; 
protected: 
    constexpr enable_shared_from_this() : __weak_this() { } 
    enable_shared_from_this(enable_shared_from_this const &) { } 
    enable_shared_from_this& operator=(enable_shared_from_this const &) { return *this; } 
    ~enable_shared_from_this() { } 
public: 
    shared_ptr<T> shared_from_this() { return shared_ptr<T>(__weak_this); } 
    shared_ptr<T const> shared_from_this() const { return shared_ptr<T const>(__weak_this); } 
}; 

shared_ptrコンストラクタenable_shared_from_thisベースに新しく作成したshared_ptr__weak_thisメンバーに割り当てます。 - エンドノート]

あなたもノートでこれを言及するためにリンクされcppreference page

+0

ありがとうございます。私はまだこれが微妙なエラーの原因だと思っていますが、どのような種類の静的なアサーションでも検出できないと思います。 –

+0

@ArtificialMind: 'static_assert(std :: is_convertible :: value、"公開継承が必要です ");'(これを仮定すると、 'std :: enable_shared_from_this'実装に次のようなものを追加できました。上記の実装) –

1

あなたの質問のコードは、プライベート継承をまったく使用していません。structは、メンバーとベースクラスの両方に対してパブリックアクセスコントロールにデフォルト設定されています。

さらに、cppreferenceは何も省略しません。ページのテキストが明確に述べている:公的std::enable_shared_from_this<T>から継承

... [bad_weak_ptr原因shared_from_this]の

(重点鉱山)

+0

気付いてくれてありがとう!私のプロダクションコードはクラスを使用しているので、そこでは失敗しました。少なくともcppの参照は一貫しています。 –