I'm fairly new to C .
Have a struct Bbox
with a constructor with two arguments x
and y
which I have just added. Before when the constructor had no arguments I could initiate multiple instances of Bbox
by doing this and num_components
was the number of instances I wanted to create:
Bbox list [num_components];
But how can I do that now when the constructor require arguments?
struct Bbox {
int
left,
top,
right = 0,
bottom = 0,
mat_width,
mat_height;
Bbox(int x, int y):
left(std::numeric_limits<int>::max()),
top(std::numeric_limits<int>::max()),
mat_width(x),
mat_height(y)
{}
};
The arguments to initiate the list of Bbox
are always the same. Lets say x=10
and y=20
but don't want to add default values to the construtor because the values can vary
CodePudding user response:
And, to build on @anoop's (excellent) answer, if you use std::vector
instead of a C-style array (and you should!), then you can do this:
std::vector <Box> make_boxes (int num_boxes)
{
return std::vector <Box> (num_boxes);
}
And you would call it thus:
auto my_boxes = make_boxes (10);
But make_boxes
is so trivial that it's hardly worth factoring it out, really.
If you want make_boxes
to construct boxes with a size specified by the caller, then this would do the job:
std::vector <Box> make_boxes (int num_boxes, int x, int y)
{
std::vector <Box> boxes;
boxes.reserve (num_boxes);
for (int i = 0; i < num_boxes; i)
boxes.emplace_back (x, y);
return boxes;
}
and then:
auto boxes = make_boxes (10, 10, 20);
CodePudding user response:
The arguments to initiate the list of Bbox are always the same. Lets say x=10 and y=20
You can add a default constructor that will delegate the work to the parameterized constructor by passing the argument 10
and 20
as shown below:
struct Bbox{
//other parameterized constructor as before
//----------vvvvvvvvvvv------>delegate the work to parameterized ctor
Bbox(): Bbox(10, 20) //this is a default ctor delegating the work to the other ctor
{
}
};
Bbox list[num_components]; //works now assuming num_components is a constant expression
CodePudding user response:
Use curly-brackets to initialize the array:
Bbox list [num_components] = {
// ...
};
Then for each Bbox
object you need curly-braces again:
{ SOME_X, SOME_Y }
Combined it would be like:
Bbox list [num_components] = {
{ SOME_X, SOME_Y },
// ...
{ SOME_OTHER_X, SOME_OTHER_Y }
};
If you want to be able to create default-constructed Bbox
object, without any explicit initialization, you must create a Bbox
default constructor.
Now remember that an array have a size that is fixed at the time of compilation. They also tend to decay to pointers when least wanted.
If you need a dynamic "array" whose size doesn't have to be known at compile-time, and where you can add or remove elements at run-time, you should use std::vector
:
std::vector<Bbox> list;
You can initialize it just like for arrays, or add elements later when needed:
list.emplace_back(some_x, some_y);
As a vector is an "object", it's also easy to pass copies of it to function, or passing references if you have a lot of elements in it. It keeps track of its own size, you can easily loop over a vector, and use many of the nice algorithms available in the standard library. Well you can do this with array, and even pointers, but it's easier with a vector.