私はこれを持っています:
std::vector <BinaryTree*> children;
BinaryTree
クラスはどこですか。このベクトルに要素を追加するにはどうすればよいですか?
クラスのインスタンスであるchildren.push_back(X)
場所を試しましたが、次のエラーが表示されます。X
パラメータ 1 を 'BinaryTree' から 'BinaryTree *&&' に変換できません
を使用して、 のインスタンスへのポインターpush_back()
を渡すだけです。BinaryTree
std::vector <BinaryTree*> children;
BinaryTree* pTree = new BinaryTree();
children.push_back(pTree);
...
delete pTree;
手動のメモリ管理を避けるために、参照セマンティクスが必要な場合は、生のポインターの代わりにスマート ポインターを使用します。
#include <memory> // For std::shared_ptr
std::vector <std::shared_ptr<BinaryTree>> children;
std::shared_ptr<BinaryTree> pTree = std::make_shared<BinaryTree>();
children.push_back(pTree);
...
// No need to delete pTree
std::shared_ptr<>
クラス テンプレートは、C++11 標準ライブラリの一部です。C++03 では、(ほぼ) 同等のものを使用できますboost::shared_ptr<>
。
#include <boost/shared_ptr.hpp> // For std::shared_ptr
std::vector <boost::shared_ptr<BinaryTree>> children;
boost::shared_ptr<BinaryTree> pTree = boost::make_shared<BinaryTree>();
children.push_back(pTree);
...
// No need to delete pTree
最後に、参照セマンティクスがまったく必要なく、代わりにバイナリ ツリーを値として扱いたい場合は、次のように定義することも検討できますstd::vector<BinaryTree>
。
std::vector<BinaryTree> children;
BinaryTree tree;
children.push_back(tree);
*
テンプレート引数からアスタリスクを省略します。
std::vector<BinaryTree> children;
のように手動/動的メモリ割り当てなしで、子にデータを保持させたい場合new BinaryTree
。
それは、誰がポインタを所有することになっているかに大きく依存します。ベクターがそれらを所有していない最も単純なケースでは、BinaryTree
オブジェクトのアドレスを渡します。
BinaryTree b = ...;
children.push_back(&b);
しかしb
、少なくとも同じくらい長く生きていることを確認する必要がchildren
あります。
ベクターがポインターを所有している場合は、おそらくスマート ポインターを格納して、メモリ管理に対処する必要がないようにする必要があります。
std::vector<std::unique_ptr<BinaryTree>> children;
children.push_back(std::unique_ptr<BinaryTree>(new BinaryTree(args)));
このすべての「所有権」ビジネスが何を意味するのかがわからない場合は、オブジェクトの単純なベクトルを使用する方がよいでしょう。
std::vector<BinaryTree> children;
std::vector<SomeObject*> objectVector;
objectVector.push_back(new SomeObject());
私のやり方です。
あなたはポインタのベクトルを持っています:
std::vector <BinaryTree*> children;
したがって、要素を追加する適切な方法は次のとおりです。
BinaryTree* child = new BinaryTree();
children.push_back(child);
このようなことをしている間は注意してください:
{
BinaryTree child;
children.push_back(&child);
}
そのような要素の有効期間はベクターの有効期間よりも短い可能性があり、存在しなくなった要素 (ダングリング ポインター) にアクセスしようとしてしまい、未定義の動作が発生する可能性があるためです。delete
また、使い終わったら、これらの要素を忘れないでください。
しかし、最初にオブジェクトのベクトルを使用することを検討することは常に良いことです (つまりstd::vector<BinaryTree>
)。
children.push_back(&X);
これは機能しますが、オブジェクトがスコープを離れると、そのデリータが呼び出され、無効なポインターが残ることに注意してください。
には、 型のオブジェクトへのポインタがvector
含まれています。あなたが必要BinaryTree
BinaryTree bt;
children.push_back( &bt );
ただし、オブジェクトの有効期間がbt
少なくともvector
.
代わりにこれが必要な場合があります
children.push_back( new BinaryTree );
ただし、この場合、メモリ リークを防ぐためdelete
に、 に含まれるポインタを呼び出す必要があります。vector
明らかなように、どちらのオプションも管理が容易ではありません。簡単な変更は、コンテナーに要素を値で格納するようにすることです。
std::vector<BinaryTree> children;
BinaryTree bt;
children.push_back( bt );
ポインタを格納する必要がある場合は、代わりにスマート ポインタを使用してそれらを保持します。
std::vector<std::unique_ptr<BinaryTree>> children;
children.push_back( new BinaryTree );
これで、ベクトルを空にする前にオブジェクトを削除することを心配する必要がなくなりました。
children.push_back(&X);
アドレスをポインターとして使用しているかのように渡します。しかし、問題はそのインスタンスが範囲外になった場合です。
BinaryTree* X = new BinaryTree;
children.push_back(X);
これにより、X が範囲外に出ることはありませんが、使い終わったら手動で削除する必要があります。