Sign in to follow this  
ukdeveloper

Struct declaration issues

Recommended Posts

I'm getting errors when I create an instance of my struct. Here's the code:
struct pong_ball
{
       SDL_Rect b_rect;
       
       vector2f position;
       
       vector2f direction;
       
       float speed;
       
};

pong_ball g_ball;

And the errors I'm getting are: 36 C:\Documents and Settings\FINALPONG\main.cpp no matching function for call to `pong_ball::pong_ball()' note C:\Documents and Settings\FINALPONG\main.cpp:25 candidates are: pong_ball::pong_ball(const pong_ball&) I just don't get it, it's not a class, so why is it looking for a constructor?

Share this post


Link to post
Share on other sites
A struct and a class are the same thing except that structs are public by default and classes are private.

Probably vector2f doesn't have a default constructor and pong_ball needs to construct them explicitely.

Share this post


Link to post
Share on other sites
Here's vector2f.h. chad_420 gave it to me because I was having trouble before:



#include <cmath>


struct vector2f
{
float x,y;

vector2f(float x_, float y_) : x(x_), y(y_) {}

void normalize()
{
if(x != 0 && y != 0)
{
float len = sqrt(x*x + y*y);
x /= len;
y /= len;
}
}

vector2f vabs()
{
vector2f temp(0,0);
temp.x = abs(x);
temp.y = abs(y);
return temp;
}

//Operator Overloads...
//+= and -=
vector2f operator+=(vector2f const& other)
{
return vector2f(x + other.x,y + other.y);
}

vector2f operator-=(vector2f const& other)
{
return vector2f(x - other.x,y - other.y);
}

// vector2f, int, float subtraction
vector2f operator-(vector2f const& other)
{
return vector2f(x - other.x, y - other.y);
}

vector2f operator-(int const& other)
{
return vector2f(x - other, y - other);
}

vector2f operator-(float const& other)
{
return vector2f(x - other, y - other);
}

// vector2f, int, float addition
vector2f operator+(vector2f const& other)
{
return vector2f(x + other.x, y + other.y);
}

vector2f operator+(int const& other)
{
return vector2f(x + other, y + other);
}

vector2f operator+(float const& other)
{
return vector2f(x + other, y + other);
}

// vector2f, int, float multiplication
vector2f operator*(vector2f const& other)
{
return vector2f(x * other.x, y * other.y);
}

vector2f operator*(int const& other)
{
return vector2f(x * other, y * other);
}

vector2f operator*(float const& other)
{
return vector2f(x * other, y * other);
}

// vector2f, int, float division
vector2f operator/(vector2f const& other)
{
return vector2f(x / other.x, y / other.y);
}

vector2f operator/(int const& other)
{
return vector2f(x / other, y / other);
}

vector2f operator/(float const& other)
{
return vector2f(x / other, y / other);
}

//logical operator overloads... int,float and vector for > < but not ==
//
int operator==(vector2f const& other)
{
if(abs(x - other.x) < 1 && abs(y - other.y) < 1)
return 1;
else return 0;
}

//Greater than
int operator>(vector2f const& other)
{
if(x >= other.x && y >= other.y) return 1;
else return 0;
}

int operator>(int const& other)
{
if(x >= other && y >= other) return 1;
else return 0;
}

int operator>(float const& other)
{
if(x > other && y > other) return 1;
else return 0;
}

//Less than
int operator<(vector2f const& other)
{
if(x < other.x && y < other.y) return 1;
else return 0;
}

int operator<(int const& other)
{
if(x < other && y < other) return 1;
else return 0;
}

int operator<(float const& other)
{
if(x < other && y < other) return 1;
else return 0;
}

};


Share this post


Link to post
Share on other sites
Hi,

Put in another constructor for vector2f and a set function:-


vector2f::vector2f()
{
x = 0;
y = 0;
}

void vector2f::set(float inX, float inY)
{
x = inX;
y = inY;
}




Ohterwise you need to make those vector2f pointers and allocate memory at run time. With the vector2f you have right now this is how it will probably work


struct pong_ball
{
SDL_Rect b_rect;

vector2f *position;

vector2f *direction;

float speed;

};

pong_ball b;
b.position = new vector2f(10, 20); // example data
b.direction = new vector2f(1, 1); // example data
b.speed = 0.4f; // example data




With respect to the exact error you are getting, do you have a constructor for pong_ball as well which goes like pong_ball(const pong_ball &). In my opinion its best to always create a constructor which accepts no value and set member variables to default in all cases. For eg:-


struct pong_ball
{
pong_ball()
{
position.set(0, 0);
direction.set(0, 0);

speed = 0;
b_rect.width = b.rect.height = b_rect.x = b_rect.y = 0;
}

SDL_Rect b_rect;

vector2f position;

vector2f direction;

float speed;

};








Share this post


Link to post
Share on other sites
Thanks for your help, but there's still a problem.

Here's my code now:


struct pong_ball
{
SDL_Rect b_rect;

vector2f *position;

vector2f *direction;

float speed;

};

pong_ball g_ball;
g_ball.position=new vector2f(25, 50);
g_ball.direction=new vector2f(1.0, 1.0);
g_ball.speed=0.5f;



But now I get

39 C:\Documents and Settings\FINALPONG\main.cpp expected constructor, destructor, or type conversion before '.' token

39 C:\Documents and SettingsFINALPONG\main.cpp expected `,' or `;' before '.' token


For each of the g_ball. lines. Any ideas?

Share this post


Link to post
Share on other sites
The constructore should be in the struct:

struct pong_ball
{
SDL_Rect b_rect;

vector2f *position;

vector2f *direction;

float speed;

pong_ball() {
position=new vector2f(25, 50);
direction=new vector2f(1.0, 1.0);
speed=0.5f;
}
};


Share this post


Link to post
Share on other sites
Sorry, but I don't agree with some of the advice you've been given. The original answering posters were correct with their assessments - the changes in response to those we're all you needed to make.

The problem came with the constructor. A struct and a class are virtually the same thing, as noted by AnonMike (although there is another difference you don't need to know about yet). Every class / struct has a constructor - if you don't specify one, a default constructor will be provided for that class, but with no parameters.

(Loosely) When a function is called, the function is matched to those functions with the same name and same parameter sets. With your original pong_ball code you have provided no user-defined constructor, so a default one is provided. In the process of this constructor running, it tries to create instances of each member - including the two vector2f members. Because this is a default constructor, it tries to default construct (that is, runs a parameter-free constructor) for each of these 2 instances.

Unfortunately, your vector2f code has no parameter-free constructor - it only has vector2f(float x_, float y_). Therefore there is no matching function for the constructor to call. Therefore the constructor of pong_ball fails.

This is what CRACK123 is getting at. You need to either provide a user-written constructor for pong_ball that meets the required criteria, or provide a parameter-free constructor in vector2f.

Quote:

Ohterwise you need to make those vector2f pointers and allocate memory at run time. With the vector2f you have right now this is how it will probably work


There is absolutely no need to change vector2f to vector2f* - and given the later question on . versus -> all you've done is complicated the issue. In addition, if you're using pointer members, there are several other things you need to think about that have not been addressed. Go back to the original code (example below).

Quote:

With respect to the exact error you are getting, do you have a constructor for pong_ball as well which goes like pong_ball(const pong_ball &). In my opinion its best to always create a constructor which accepts no value and set member variables to default in all cases.


Why are you bringing up the copy constructor? In addition, I disagree with always providing a parameter-free constructor and setting everything to default. Not everything has a default. Assuming in this particular code that vector2f is a point you're assuming that that (0,0) is the default starting position for the ball. How is that sensible? Assuming direction is a orientation vector, default setting it to (0,0) also makes no sense. This is a prime example of why assuming default values are a bad idea.

So, finally, some suggested code for ukdeveloper:


struct pong_ball
{
// Here is the provided constructor
// Note that I know nothing about SDL_Rect's initialisation requirements - adjust to fit
pong_ball(const vector2f& pos, const vector2f& dir, float spd) :
position(pos), direction(dir), speed(spd) {}

SDL_Rect b_rect;

vector2f position;

vector2f direction;

float speed;

};

// Note start values should be changed to whatever's appropriate
pong_ball g_ball(vector2(10.0f,10.0f), vector2(1.0f,0.0f), 1.0f);





Of course, this means you now need a copy constructor in the vector2f class (as I didn't spot one on quick look through) - so add, after the normal constructor:


vector2f(const vector2f& vec) : x(vex.x), y(vec.y) {}





And hopefully Bob's your uncle's second cousin.

Jim.

Edit: And neither CRACK123 or cyberfox deal with deletion of the new'ed element. This is important if you're going to use pointer members.

Share this post


Link to post
Share on other sites
I tend to disagree with you in some points…

Sure this object may not logically have a default, but there is no reason why you cannot set it to some junk value for the sake of changing later (in an external initialization routine or a load function). You should never block off this option.

So an empty constructor is very handy:
class something {
something() {}
}

Share this post


Link to post
Share on other sites
Quote:

I tend to disagree with you in some points…

Sure this object may not logically have a default, but there is no reason why you cannot set it to some junk value for the sake of changing later (in an external initialization routine or a load function). You should never block off this option.


OK, difference of opinion. But I would rather build the object as fully as possible with the constructor. If I'm going to load in info from an external file I would delay construction of the object until I have the required info. To me, it's the same situation as:

int a;
//Do some stuff
// Do something with a

versus

// Do some stuff
// Initialise and do something with a

Which I believe is frowned down upon (have a look at Code Complete, for example).

Jim.

Share this post


Link to post
Share on other sites
Quote:
Original post by JimPrice
Quote:

Ohterwise you need to make those vector2f pointers and allocate memory at run time. With the vector2f you have right now this is how it will probably work


There is absolutely no need to change vector2f to vector2f* - and given the later question on . versus -> all you've done is complicated the issue. In addition, if you're using pointer members, there are several other things you need to think about that have not been addressed. Go back to the original code (example below).

Agreed.
Quote:

Quote:

With respect to the exact error you are getting, do you have a constructor for pong_ball as well which goes like pong_ball(const pong_ball &). In my opinion its best to always create a constructor which accepts no value and set member variables to default in all cases.


Why are you bringing up the copy constructor? In addition, I disagree with always providing a parameter-free constructor and setting everything to default. Not everything has a default. Assuming in this particular code that vector2f is a point you're assuming that that (0,0) is the default starting position for the ball. How is that sensible? Assuming direction is a orientation vector, default setting it to (0,0) also makes no sense. This is a prime example of why assuming default values are a bad idea.

It may very well make sense, it depends on the context and usage of vector2f. Although I do agree with you for "this case" based on the code shown.
Quote:

Of course, this means you now need a copy constructor in the vector2f class (as I didn't spot one on quick look through) - so add, after the normal constructor:

No, actually he doesn't. A default copy constructor and assignment operator are already provided.

Share this post


Link to post
Share on other sites
Quote:

It may very well make sense, it depends on the context and usage of vector2f. Although I do agree with you for "this case" based on the code shown.


I've stated my opinion, but I bow to others with greater experience[smile]. Personally I'd still prefer to not default construct in the majority of cases - in my opinion, that's what the constructor is for.

Quote:

No, actually he doesn't. A default copy constructor and assignment operator are already provided.


D'oh! Of course he doesn't. My bad....

Jim.

Share this post


Link to post
Share on other sites
Quote:

Ohterwise you need to make those vector2f pointers and allocate memory at run time. With the vector2f you have right now this is how it will probably work


Actually the default constructors slipped my mind. My mistake entirely. I had no intention of expecting him to use it though.

Quote:

Edit: And neither CRACK123 or cyberfox deal with deletion of the new'ed element. This is important if you're going to use pointer members.

[/quote]

No I don't because I expected the original poster to be comfortable enough to know about freeing dynamically allocated variables.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this