Reputation: 263
So imagine I have a struct
struct Square{
int width;
int height;
};
Then i have a function somewhere in my code
void create_vec_squares(std::vector<Square> &dest){
for(int i = 0; i < 10; i++){
//create squares and put then into the destination vector
}
}
What is considered the proper way to do this in C++? I know some C, and my immediate thought is to use memory allocation techniques such as malloc. But, i will need to throw in a void delete_vec_squares(...) to make sure the memory is properly freed.
I was wondering if any issues could arise with this method
void create_vec_squares(std::vector<Square> &dest){
for(int i = 0; i < 10; i++){
int val1,val2;
//generate some values for squares
...
//end generation
dest.push_back({val1, val2});
}
}
From my understanding, instead of allocating memory on the heap, the structures will simply be pushed onto the stack and there will be no need for manual memory allocation techniques;
Upvotes: 1
Views: 95
Reputation: 761
If you exactly know that ten objects are to be set in dest
, the following approach may be cleaner and faster:
struct Square{
int width;
int height;
Square & set(int p_width, int p_height) {
width = p_width; height = p_height;
return (*this);
}
};
typedef std::vector<Square> Square_vec;
void create_vec_squares(Square_vec & dest){
//create squares
dest.reasize(10);
for(Square_vec::iterator v_i = dest.begin(), v_e = dest.end(); v_i < v_e; ++v_i){
// and put then into the destination vector
v_i->set(val1, val2); //The already created Square object is set whithout temporary.
//Or if you have common temporay Square object:
*v_i = tmpSquare;
}
}
Next step of refactorring may be creating a functor for filling up Square_vec substituted into the for_each
function from <algorithm>
instead of the for(Square_vec::iterator ...
loop.
Upvotes: 0
Reputation: 33106
I was wondering if any issues could arise with this method
void create_vec_squares(std::vector<Square> &dest){
for(int i = 0; i < 10; i++){
int val1,val2;
//generate some values for squares
...
//end generation
dest.push_back({val1, val2});
}
}
The only issue with this method is that your code might not be portable. Some places are still stuck with C++03 compilers, which doesn't have uniform initialization.
With regard to the proper methodology, there is no one proper methodology. Uniform initialization is great when you can use it. You can't always use it (even in C++11 and higher). Sometimes you need to use an explicit constructor, sometimes you need to operate on the item before adding it to the container. There's still no need for new
and delete
. Just declare a local variable and push that back onto the container.
When you know you are going to drop a boatload of objects onto a vector, it can be advantageous to reserve some space for that incoming boatload. Your code with a boatload (10000) objects instead of just 10:
void create_vec_squares(std::vector<Square> &dest){
dest.reserve(dest.size() + 10000);
for(int i = 0; i < 10000; i++){
int val1,val2;
//generate some values for squares
...
//end generation
dest.push_back({val1, val2});
}
}
Upvotes: 0
Reputation: 5683
instead of allocating memory on the heap, the structures will simply be pushed onto the stack and there will be no need for manual memory allocation techniques;
You are right. When you push_back, you just need to push_back, because
std::vector<T>::push_back(const T & val);
is copy-based.
Your Square
object will be safely kept in std::vector<Square>
out of scope.
If you do some allocation in Square
, then it's Square::~Square()
's job to free what's needed to be.
Upvotes: 1
Reputation: 853
push_back
is a vector method that adds a new element at the end of the vector, after its current last element.
You can do the following:
void create_vec_squares(std::vector<Square> &dest){
for(int i = 0; i < 10; i++){
//create an object Square and lets call it newSquare, then you can use push_back
dest.push_back(newSquare);
//this will add your object newSquare at the end of vector dest
}
}
And if you want to empty the vector entirely, you can use dest.clear()
.By using the included methods it decreases the chances of mismanaging an object vector
and is generally safer.
Upvotes: 0