I have a class, user, which stores objects of another class, foo, in a vector. I am trying to figure out what is the best way of creating objects of class foo and store them in vector of class user.
class Foo { public: Foo(); Foo(std::string str); std::string name; Foo* GiveMeFoo(std::string arg); }; Foo::Foo() {} Foo::Foo(std::string args):name(args) {} Foo* Foo::GiveMeFoo(std::string arg) { return new Foo(arg) }; class User { public: vector < Foo *> v; vector < Foo> v2; vector < Foo*> v3; void start(); }; void User::start() { const int SIZE = 3; string a[SIZE] = {"one","two","three"}; for (int i = 0; i < SIZE; i++ ){ //method1 Foo *f = new Foo(开发者_如何学JAVA); f->name = a[i]; v.push_back(f); //method2 Foo f2; f2.name = a[j]; v2.push_back(f2); //method3 Foo f3; v3.push_back(f3.GiveMeFoo(a[k])); } }
Question1: Between methods 1, 2 and 3 is there a preferred way of doing things? Is there a better way of creating objects of remote class locally and storing them in a vector?
Question 2: Are all the objects that are getting stored in the vectors of class User persistent (e.g. even if the foo object goes away, once I have pushed those objects onto vector in user, then copies of those foo objects will be persistently stored in the vector, correct?
Unless there are other considerations, method 2 is preferred.
Vectors (and other STL containers) store copies of the argument to push_back().
This means that for method 1, you are allocating a Foo on the heap and then storing a pointer to it in the vector. If the User object is destroyed, the Foo objects will leak unless you take steps to delete them (like delete them in the User destructor).
For method 2, you have allocated a Foo on the stack. This object is then copied into the vector. When start() exits, the original Foo is destroyed but the copy survives in the vector. If the User object is destroyed then so is the vector and consequently the Foo.
For method 3, you have allocated a Foo on the stack. You then call GiveMeFoo() on it which allocates another Foo on the heap and then returns a pointer to it. This pointer is then copied into the vector. When start() exits, the original Foo will be destroyed but the heap allocated object will survive. If the User object is destroyed then so is the vector but the heap allocated Foo survives and leaks unless you destroy it manually in the destructor of User.
If you need to store a pointer to an object rather than a copy then you are better off using std::tr1::shared_ptr (if your compiler supports it) to manage the lifetime of the Foo objects.
In case it helps someone, as of C++11, std::vector (along with some of the other STL containers) now have the ability to "emplace" an instance into the collection. This has the advantage of avoiding a possible extra duplicate object or copy.
For the example above, code like this can be used instead:
v.emplace_back(a[i]);
More information: std::vector::emplace_back
精彩评论