Which one is better?

Say I have a FOO class.

I want to have std::vector FOO.

Am I better off doing something like this:

 FOO foo; foo.init(); foo.prop = 1; std::vector<FOO> myvec; myvec.push_back(foo); foo.prop = 2; myvect.push_back(foo); 

or better to do this:

 std::vector<FOO> myvec; FOO foo; myvec.push_back(foo); myvec.back().init(); myvec.back().prop = 1; myvec.push_back(foo); myvec.back().init(); myvec.back().prop = 2; 

In principle, I’m not sure that it’s better to make a model and click on a model instead of making an instance, pushing it, and then changing it from a vector. Also, which one is safer and least likely to lead to memory leaks?

thanks

+4
source share
5 answers

None of the methods have memory problems, because you are dealing with values ​​and do not dynamically allocate any objects manually.

I would like to give a FOO constructor that does everything init and sets prop to the appropriate value. Then you can simply click on the desired values:

 myvec.push_back(FOO(1)); myvec.push_back(FOO(2)); 
+8
source

It is best not to have an init () function - you want a constructor. If you always need to install a support, give the constructor a parameter for this. This has nothing to do with vectors - this is the way all C ++ code should be written.

+10
source

I think the best is:

 myvec.push_back(FOO(1)); myvec.push_back(FOO(2)); 
+1
source

The answer depends on what your FOO class does. If this is a simple structure without pointers, etc., then both approaches fit together and do the same.

Note that push_back inserts a copy of the object into the vector. If your class allocates memory on the heap, you need a copy constructor that creates a deep copy of your objects, otherwise you will get memory leaks. Also, if your objects are large enough, making copies can be inefficient. In such cases, I usually select the object itself on the heap and insert the pointer into the vector:

 std::vector<FOO *> myvec; FOO *foo; foo = new FOO(); foo->init(); foo->val = 1; myvec.push_back(foo); foo = new FOO(); foo->init(); foo->val = 2; myvec.push_back(foo); 

However, in this case, you need to remember the release of objects before destroying the vector.

+1
source

Besides what others have said about initializing your objects in the constructor, I would add the following:

In your second example, where you put objects in a vector and then initialize them, you risk leaving your vector in an unusable state.

If, for example, the init () method can throw an exception, an object with incomplete or partially initialized objects will be created in your vector.

Of course, these problems go away with the constructor, which guarantees the correct initialization of objects.

In general: don't start doing things with objects before they are in a healthy state.

0
source

Source: https://habr.com/ru/post/1314676/


All Articles