2016-06-24 3 views
1

私はこのコードを持っている:私はこのプログラムを実行するとenable_shared_from_これは、unique_ptrから基本クラスへのshared_ptrの使用中に初期化されませんでした。どうして?

#include <iostream> 
#include <memory> 
#include <string> 

class base { 
public: 
    virtual void method() = 0; 
    virtual ~base() = default; 
}; 

class test: public base, public std::enable_shared_from_this<test> { 
private: 
    std::string text; 
public: 
    test(std::string text): text(std::move(text)) {} 
    ~test() = default; 
    virtual void method() override { 
    std::cout << "text: " << text; 
    std::cout << " this: " << this->shared_from_this().get() << std::endl; 
    } 
    static std::unique_ptr<base> create(std::string text) { 
    return std::unique_ptr<base>(new test(std::move(text))); 
    } 
}; 

static auto create_test(std::string text) { 
    return test::create(std::move(text)); 
} 

int main(int argc, char* argv[]) { 
    std::shared_ptr<base> shared = create_test("some text"); 
    shared->method(); 
    return 0; 
} 

は私が例外「bad_weak_ptr」を取得します。 「enable_shared_from_this」が初期化されていない理由を説明できますか?

unique_ptr<base>のインスタンスをunique_ptr<test>に変更すると動作します。

$ ./test 
terminate called after throwing an instance of 'std::bad_weak_ptr' 
    what(): bad_weak_ptr 
text: some textAborted (core dumped) 
+0

私はこれまで、ファクトリ関数は 'unique_ptr'を返さなければならないと言ってきましたが、ポインタが工場から返された時点で既に共有されている必要はありません。あなたのクラスが 'shared_from_this'を継承する場合、ファクトリが返ってくると2つのポインタがすでに存在します。実際には、[元のコメントでそのケースを明示的に呼び出しました](https://stackoverflow.com/questions/35953783/c11-make-shared-instancing#comment59565062_35953783)誰かがあなたに 'unique_ptr'と' shared_from_this'を一緒にして例外があると教えてください。 –

答えて

1

他に何を期待しましたか? shared_ptr<base>を使用しています。ベースはenable_shared_from_thisから除外されていないので、共有ポインタはshared_from_thisによって使用される弱い参照を初期化できません。

設計どおりに動作します。

0

あなたはこのcreate機能を使用してbaseに1へtestの外に構築された共有ポインタをキャストすることができます

static std::shared_ptr<base> create(std::string text) { 
    return std::shared_ptr<test>(new test(std::move(text))); 
} 

そうでない場合、それは動作しません。
enable_shared_from_this期待通りに動作しますが、検討しthis

のstd :: enable_shared_from_thisは、PT2、現在、安全に、追加のstd :: shared_ptrのインスタンスのPT1を生成するために、PTという名前のstd :: shared_ptrのによって管理されているオブジェクトtを可能に...すべてがptとtの所有権を共有する。

コードでは、testのうちshared_pointerは作成されていません。
上記の機能はcreateです。

関連する問題