/* bar.h */
class bar{
/* standard stuff omitted */
std::vector<my_obj*> foo;
};
/* bar.cpp */
bar::bar(){
// foo = new std::vector<my_obj*>(); <-- why don't I need this line??
foo.Push_back(new my_obj());
}
Fooにstd :: vectorの新しいインスタンスを割り当てなかったのに、なぜこのコードが機能するのですか?
C++はC#/ Javaではないからです。
std::vector<my_obj*> foo;
これはobjectの定義であり、C#/ Javaのような参照ではありません。オブジェクトは型の生きたインスタンスです。
new std::vector<my_obj*>()
この式はpointerを返します。 std::vector<my_obj*>*
を返します。これはnotfoo
と同じ型です(末尾の*
が違います)。 foo
はオブジェクト、std::vector<my_obj*>*
はオブジェクトへのポインターです。
オブジェクトには(ポインタや参照ではなく)特定の有効期間があります。 new
を使用してオブジェクトへのポインターを作成した場合、delete
を明示的に呼び出すまで、ポイントされたオブジェクトの有効期間は残ります。オブジェクトを別のオブジェクトのメンバーとして作成すると、その内側のオブジェクトの寿命は(おおよそ)外側のオブジェクトの寿命を反映します。スタック上にオブジェクト(関数スコープのパラメーターまたは変数)を作成する場合、その有効期間はその変数名の現在のスコープです。
bar
にはstd::vector
ではなくstd::vector *
が含まれているためです。
これは本当にこのようなものと違いはありません:
class bar
{
int foo; // No need to create a "new int"
};
Fooはポインターではなくオブジェクトだからです。
std::vector<my_obj*> // This is an object
std::vector<my_obj*> * // This is a pointer to an object
^^^ // Notice the extra star.
新しいポインタを返します:
new std::vector<my_obj*>(); // returns std::vector<my_obj*> *
PS。ベクトルには、ポインタではなくオブジェクトが含まれている可能性があります。
std::vector<my_obj> foo;
...
foo.Push_back(my_obj());
それ以外の場合は、ベクターがスコープ外になったとき(含まれているオブジェクトが破棄されたとき)に、ベクター内のすべてのオブジェクトを手動で削除する必要があります。つまり、ベクターにポインターを保持する場合は、次のいずれかを実行する必要があります。
// 1. Manually delete all the elements in the vector when the object is destroyed.
~bar::bar()
{
for(std::vector<my_obj*>::iterator loop = foo.begin(); loop != foo.end(); ++loop)
{
delete (*loop);
}
}
// 2. Use a smart pointer:
std::vector<std::shared_ptr<my_obj> > foo;
// 3. Use a smart container for pointers
boost::ptr_vector<my_obj> foo
std::vector
があなたのためにそれを行うので:)あなたはstd::vector
へのポインタを持っていないので、メモリを内部的に割り当てるstd::vector
型のオブジェクトを設定するだけです。
このライブラリのstd :: vectorはポインタではありません
Fooはnew
へのポインターではなくfoo
であるため、vector
でvector
を使用する必要はありません(つまり、std::vector<my_obj*> *foo
)。
JavaまたはC#から来ている場合は、std::vector<my_obj>
(オブジェクトのベクトル)ポインターのベクトルの代わりに。本当に何をしたいかに依存します。
std::vector<my_obj *> foo
はstd::vector<my_obj *> *foo
とは異なります。 2番目のケースではnewを使用する必要がありますが、最初のケースでは使用しません。