passing structures as pointers through functions [ERROR] why?

Started by
12 comments, last by Morrandir 15 years, 10 months ago
I'm wondering why my code isn't working as I want it to work. I have small header file. Called Particle.h

#ifndef PARTICLE_H
#define PARTICLE_H

#include <math.h>
#include <SDL\SDL.h>
#include <SDL\SDL_gfxPrimitives.h>

#define NUM 75



class Particle
{
public:

	Particle();
	~Particle();

	void reset_particles(int n);
	void update(SDL_Surface* screen);
	void reset_all();
	void attract(struct particles *A, struct particles *B);
	void render(SDL_Surface* screen);



private:

	struct particles
	{
		double mass;
		double x, y;
		long oldX, oldY;
		long xp, yp;
		double ax, ay, vx, vy;
	}p[NUM];

	int cx, cy;


};

#endif



#include "Particle.h"
#include "Globals.h"

Particle::Particle()
{
}

Particle::~Particle()
{
}

void Particle::attract(struct particles *A, struct particles *B)
{
	double distance;
	double dist, distX, distY;
	double transX, transY;

	//increase the vector position of particle by it's velocity it's respected direction
	A->x += A->vx;
	A->y += A->vy;

	//calculate the distance between particles
	distX = A->x - B->x;
	distY = A->y - B->y;
	dist = distX*distX + distY*distY;

	if(dist != 0)
	{
		distance = 1/dist;
	}
	else dist = 0;

	transX = distX*distance;
	transY = distY*distance;

	//accelerate each particle acceleration (m*d)
	A->ax = -1 * B->mass * transX;
	A->ay = -1 * B->mass * transY;

	//increase velocity by acceleration value
	A->vx += A->ax;
	A->vy += A->ay;

	//scale position to the screen
	A->xp = cx + A->x;
	A->yp = cy + A->y;
}

//reset a number of particles
void Particle::reset_particles(int n)
{
	p[n].mass = 0.001;
	p[n].ax = 0;
	p[n].ay = 0;
	p[n].xp = 0;
	p[n].yp = 0;
	p[n].x = rand() % width/4;
	p[n].y = rand() % height/4;
	p[n].vx = 0;
	p[n].vy = 0;
}

void Particle::reset_all()
{
	int n;
	cx = width/2;
	cy = height/2;

	for(n=0; n<NUM; n++)
		resetparticles(n);
}

void Particle::update(SDL_Surface* screen)
{
	int n;
	int i;

	//erase old particle
	for(n=0; n<NUM; n++)
	{
		circleColor(screen, p[n].oldx, p[n].oldy, 5, 33);

		//apply gravity between every particle
		for(i=0; i<NUM; i++)
		{
			if(i != n) attract(&p[n], &p);
		}

		//reset particle if it gets to far away
		if((p[n].xp < 0) || (p[n].xp > 600) || (p[n].yp < 0) || (p[n].yp > 400))
			reset_particles(n);

		//plot new particle
		circleColor(screen, p[n].xp, p[n].yp, 5, 33);

		//keep track of current position
		p[n].oldX = p[n].xp;
		p[n].oldY = p[n].yp;
	}

	//draw primary partice
	circleColor(screen, p[0].xp, p[0].yp, 5, 33);
}


I'm working with the book Game Programming All in One, and it uses Allegro to program by examples games. That's fine, I'm just trying to see how particles work, and how easy/difficult it is to make a particle system, and within chapter 2 there's a particle system, so I make it in Allegro no problem. I tried to make it myself in SDL, and I get

Particle.cpp
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(13) : error C2511: 'void Particle::attract(Particle::particles *,Particle::particles *)' : overloaded member function not found in 'Particle'
        c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.h(13) : see declaration of 'Particle'
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(70) : error C3861: 'resetparticles': identifier not found
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(81) : error C2039: 'oldx' : is not a member of 'Particle::particles'
        c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.h(30) : see declaration of 'Particle::particles'
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(81) : error C2039: 'oldy' : is not a member of 'Particle::particles'
        c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.h(30) : see declaration of 'Particle::particles'
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(86) : error C2664: 'Particle::attract' : cannot convert parameter 1 from 'Particle::particles *' to 'particles *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(94) : warning C4244: 'argument' : conversion from 'long' to 'Sint16', possible loss of data
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(94) : warning C4244: 'argument' : conversion from 'long' to 'Sint16', possible loss of data
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(102) : warning C4244: 'argument' : conversion from 'long' to 'Sint16', possible loss of data
c:\documents and settings\c.s.  finch\my documents\visual studio 2008\projects\no bs guide to sdl\part ii\breakout\breakout\particle.cpp(102) : warning C4244: 'argument' : conversion from 'long' to 'Sint16', possible loss of data
Generating Code...

is there a special way of calling structures as pointers that I'm not aware of yet ?
Advertisement
It seems strange to call

Attract( struct partices* , struct particles* );
// i think it should be
Attract( particles*, particles* );
// instead
[/code/

I am not sure if the way you are doing it is definitley wrong, but I know that my way is right...
It should be
void Particle::attract(Particle::struct particles *A, Particle::struct particles *B)

instead of
void Particle::attract(struct particles *A, struct particles *B)


@Mathmo:

can only leave the struct away if you do a typedef
Someone who uses a, euhm..., delta!?
Use Particle::particles instead of struct particles.

Quote:Original post by delta user
can only leave the struct away if you do a typedef


... or if you're using C++, which does seem to be the case here.

I have tried all above and all above has failed me miserable, or simply I'm not coding this correctly.

Is there a tutorial that will show how to do OOP passing structures as parameters through functions?

I've tried in the header file calling

void attract(struct particles *A, struct particles *B)

then in the source file

void attract(struct Particle::particles *A, struct Particle::particles *B)

and then tried

void attract(Particle::particles *A, Particle::particles *B)

and then tried

void attract(struct particles *A, struct particles *B)



all has failed me.

and everything previously mentioned by others in the community I have tried to use, but as well haven't been successful at all.

How come?
I am sure that my way should work fine provided you declare the struct outside the class - other than that I can't offer much help. Google it...

Just to repeat my way, in case you didn't understand
//headerstruct particles{}class Particle{private:     particles[NUM] m_particleArray;public:     void attract( particles*, particles* );};//in .cpp#include "ParticleSystem.h"void Particle::attract( particles* A, particles* B ){    // dostuff}


If that doesn't work try this:
//headertypedef struct particles{} * ptrToParticles;class Particle{private:     particles[NUM] m_particleArray;public:     void attract( ptrToParticles, ptrToParticles );};//in .cpp#include "ParticleSystem.h"void Particle::attract( ptrToParticles A, ptrToPrticles B ){    // dostuff}

My guess is that the compiler is getting confused because particles is a private structure definition, but you're trying to include it as part of the signature of a public function.

Move the definition of the particles struct into the public section and see if that resolves it.
oh outside the class

well see there was my error...

and I have been googling it, but why does it have to be outside the class ?

Thanks
Sandman is saying that declaring the struct privately is what made it bad;

class Particle{public:     struct particles     {     };     void Attract( particles* A, particles* B );private:     particles m_particleArray[NUM];};


would work fine, but if attract is public then then external functions or other classes have to be able to call it.

If you want particles to be private, you should be fine provided that you make attract private too, which should be fine as that is just called by your member function update, right?
EDIT: sorry about the double post

This topic is closed to new replies.

Advertisement