Snowballion Fisher
Snowballion Fisher

Reputation: 27

C++ returning struct values from functions

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

Answers (4)

Tim Randall
Tim Randall

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

R Sahu
R Sahu

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

asu
asu

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

Samy Dressel
Samy Dressel

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

Related Questions