2016-11-28 17 views
0

私はC++で学校の宿題をしています(まだ学習中です)。私はランダムに生成されたバイナリツリー構造を実装しようとしています。複数の場所にノードの情報を格納するshared_ptrを使用しています(私は宿題のために必要です)。 (これは私の小さなテストプログラムである)次のサンプルコードを考えてみましょう。この場合、C++:vectorのshared_ptrが元のshared_ptrを更新していません

#include <vector> 
#include <memory> 


struct Node : public std::enable_shared_from_this<Node> { 
    char charValue; 
    int intValue; 
    std::shared_ptr<Node > left; 
    std::shared_ptr<Node > right; 
    std::shared_ptr<Node > parent; 

    std::shared_ptr<Node> getPtr() 
    { 
     return shared_from_this(); 
    } 

    Node() : intValue(0) 
    { 
     charValue = 0; 
    } 
}; 

int main(int argc, char**argv) { 

    std::vector<std::shared_ptr<Node>> treeQueue; 
    std::shared_ptr<Node> root = std::make_shared<Node>(); 

    treeQueue.clear(); 
    treeQueue.push_back(root->left); //std::shared_ptr<Node>(root->left)); //root->left->getPtr()); 
    treeQueue.push_back(root->right); //std::shared_ptr<Node>(root->right)); //root->right->getPtr()); 

    treeQueue[1] = std::make_shared<Node>(); //std::shared_ptr<Node>(new Node); 
    system("PAUSE"); 

    return 0; 
} 

、私は根をintialize、と私はツリー構造で、それを選択するまでの空の木の他のすべてのノードを維持したいです。私の宿題では、vector treeQueueにプッシュした後、どのノードを選択するかを決めます。 (私はランダムにそこからそれを選ぶ)。

問題:たとえば、上記のコードで、treeQueue [1]を初期化すると、root-> rightも初期化されると思います。彼らは同じポインターなので。しかしそれは空のままです!私はtreeQueue(これもうまくいきませんでした)にプッシュしようとしました。私は "enable_shared_from_this"も試みました。それがそこにあるのです。

これを行う方法はありますか?または、私が必要とするのと同じ機能を提供する別のテクニックがありますか?

生ポインタを使用するのは健康ではないことを知ったので、私はshared_ptrを使用しましたが、今はこの問題が発生します。私を助けてください、私は私の心を失うつもりです。私はできる限りどこでも調べた。私は見つけたものすべてを試しました。

+0

あなたは 'root-> right'が初期化されることを期待していますか?あなたはどこにでも初期化していません。 – lcs

+0

'treeQueue [1] = std :: make_shared ()'は 'root-> right'に影響を与えません。空の' shared_ptr'( 'root-> right'のコピー)を新しい値で消去するだけです。 'std :: vector *>' ... – Jarod42

+0

私はあなたの質問を理解できません。あなたは何を達成しようとしていますか? – Barry

答えて

0

私の間違いを理解してくれたSam Varshavchikに感謝します。そして、私もJarod42の提案を受け取り、treeQueueを

として使用しました。だから私は解決策として、これらの2つのコメントへの参照としてこのコメントをマークしています:)

3

shared_ptrは、ptrが指しているものを共有します。 shared_ptr自体は、いかなる形、形、問題、または形でも「共有」されていません。同じオブジェクト(つまり共有されている)を参照する各shared_ptrは、それ自体の独立した個別の共有ポインタです。

shared_ptrを別のshared_ptrにコピーしました。次に、shared_ptrのコピーを別の新しく構築したshared_ptrと置き換えました。

新しく構築されたshared_ptrは元のshared_ptrとは全く関係がありません。最初からコピーされたものが参照しています。

あなたのコードは、次と同等です:

int *a=NULL; 

int *b=a; 

b=new int{4}; 

あなたは4を返すために*a、今、期待していますか?。もちろん違います。彼らは全く別の2つの指針です。

+0

ああ、ありがとう、ありがとう。あなたはこれを達成するために何らかの方法を提案できますか? –

+1

'Node()'のコンストラクタで左/右を初期化する必要があります。しかし、別の問題があります:もし 'shared_ptr'で完全にリンクされたツリーを作成した場合(それがコンストラクタで正しく行われたものであれ、手動であれ)循環参照(親と子の間)を作成しますメモリリークが発生します。 'shared_ptr'に関するすべてのことを学んだので、弱いポインタが何であるかを知る必要があります。 –

関連する問題