Reputation: 27
So for one of my assignments i have to generate random graphic circles and rectangles, using structures. but i cannot fathom how to get the structure to output from a functions.
struct Circle{
int x;
int y;
int radius;
int r;
int g;
int b;
};
Circle createCirc() {
int x = rand() % window_Width;
int y = rand() % window_Height;
int radius = rand() % 100;
int r = rand()%256;
int g = rand()%256;
int b = rand()%256;
return Circle(x,y,radius,r,g,b);
}
here i create the struct with basic values for the object, then i pass some data from main into this function.
Circle circle[1000];
circle[count] = createCirc();
however i cannot even get it to run as apparently when defining the struct itself it comes with this error:
main.cpp:47:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 6 were provided
I just do not understand how to pass the data from the function into the varable in main.
Upvotes: 2
Views: 115
Reputation: 4145
The following should work nicely.
struct Circle
{
Circle(); // the default constructor
int x;
int y;
int radius;
int r;
int g;
int b;
};
Circle::Circle() : // start member-initialization list
x( rand() % window_Width ),
y( rand() % window_Height ),
radius( rand() % 100 ),
r( rand()%256 ),
g( rand()%256 ),
b( rand()%256 )
{
// nothing to do!
}
I choose this implementation for a couple of reasons. The main reason is that you want to construct 1000 of these and store them in an array. When an array of objects is created (assuming it isn't an array of int
or other plain data type) the default constructor will be called for each element. That's what we defined here. And by using the member-initialization list we get those initial values into the member variables more efficiently than we would by assigning them in the body of the constructor. That isn't terribly important for int
values, but it's a good habit to get into.
Note that if you wanted to construct Circles
with other values, it would be a waste of time to use this default constructor. You'd want to define another constructor that takes parameters for size, position, and/or RGB values.
Upvotes: 0
Reputation: 206597
You can use
return Circle(x,y,radius,r,g,b);
only when there is an explicitly defined constructor that takes those arguments. Change it to:
return {x,y,radius,r,g,b};
The second form uses aggregate initialization to construct a Circle
.
Upvotes: 10
Reputation: 1914
struct Circle {
int x;
int y;
int radius;
int r;
int g;
int b;
};
You are only defining fields to the class, but not a constructor.
The ()
initialization syntax does not allow to do what you're doing.
However, C++11 aggregate-initialization can, as pointed out by @RSahu 's post.
An alternative is to define a constructor to your class, optionally using the member-initialization list (see a few reasons here why to).
Essentially, it would do what your createCirc
function is attempting to do. You would define it as such:
struct Circle {
int x, y, radius, r, g, b;
Circle();
};
Circle::Circle() :
x{rand() % window_width},
y{rand() % window_height},
radius{rand() % 100},
r{rand() % 256},
g{rand() % 256},
b{rand() % 256}
{}
This would allow you to do something like Circle myCircle;
and it will get initialized as you expect.
That being said, a constructor is not necessarily the best way to do this (IMO it hides too much behavior here) but it's a good thing to know.
Upvotes: 1
Reputation: 143
Just create a new Circle inside your createCirc()
function and return it:
Circle createCirc() {
Circle circle;
circle.x = rand() % window_Width;
circle.y = rand() % window_Height;
circle.radius = rand() % 100;
circle.r = rand()%256;
circle.g = rand()%256;
circle.b = rand()%256;
return circle;
}
Also you should think about using a vector
for dynamic allocation and storage.
Upvotes: 1