Click to See Complete Forum and Search --> : Problem setting member variable of parent class.


myranalis
May 13th, 2008, 11:26 PM
I've got a problem using a basic inheritance structures when setting the member variable of a parent class. (Hearders below all the explanation)

Essentially I'm trying create a new concrete entity (FLOOR) and set some baseic properties using the code below, but both of the calls to scale will give me a segmentation fault.


//starting block
VISIBLE_ENTITY_BASE* f = new FLOOR;
ENTITY_BASE* e = static_cast<ENTITY_BASE*> (f);

f->Scale (VECTOR_3D(1.0,2.0,1.0));
e->Scale(VECTOR_3D(1.0,2.0,1.0));


My current implementation of the Scale method is as follows:

void GEOMETRY_BASE::Scale(const VECTOR_3D s)
{
printf("scaling: %f, %f, %f\n", s.x, s.y, s.z);

VECTOR_3D tmp = VECTOR_3D(s.x, s.y, s.z);
printf("tmp: %f, %f, %f\n", s.x, s.y, s.z);

scale = VECTOR_3D(s.x, s.y, s.z);

printf("finished setting scaling\n");
}


I get:
scaling: 1.000000, 2.000000, 1.000000
tmp: 1.000000, 2.000000, 1.000000
segmentation fault!

So using my great powers of deduction the incoming vector is OK and something isn't right about the 'scale' part of that equation. But scale is not a pointer, just a normal variable, so why can't I just set it to a new vector??

I'm sure I've got to be misunderstanding something about how c++ works as I don't use it often... I'd appreciate it if someone can point me in the right direction!

Cheers

Anna


class GEOMETRY_BASE
{
protected:
VECTOR_3D scale;

GLfloat rotationAngle;
VECTOR_3D rotationVector;

VECTOR_3D translate;

public:
VECTOR_3D Scale();
void Scale(const VECTOR_3D s);

GLfloat RotationAngle();
void RotationAngle(const GLfloat a);
VECTOR_3D RotationVector();
void RotationVector(const VECTOR_3D v);

VECTOR_3D Translate();
void Translate(const VECTOR_3D t);
};

class CUBE : public GEOMETRY_BASE {

private:
static GLfloat vertices[];
static GLfloat texCoords[];
static GLubyte topIndices[]; // = {0,1,5,4};
static GLubyte backIndices[]; // = {4,5,6,7};
static GLubyte rightIndices[]; // = {1,2,6,5};
static GLubyte leftIndices[]; // = {0,4,7,3};
static GLubyte bottomIndices[]; // = {2,3,7,6};
static GLubyte frontIndices[]; // = {2,1,0,3};

public:
CUBE();
GLfloat* Vertices();
GLfloat* TextureCoords();
GLubyte* Top();
GLubyte* Back();
GLubyte* Right();
GLubyte* Left();
GLubyte* Bottom();
GLubyte* Front();
};

//base entity class. All entities used should inherit from this class.
class ENTITY_BASE
{
protected:
GEOMETRY_BASE* geometry;

public:

ENTITY_BASE();
GEOMETRY_BASE* Geometry();
void Geometry( GEOMETRY_BASE* g);

void Scale(const VECTOR_3D t);
void Translate(const VECTOR_3D t);
void RotationAngle(const GLfloat a);
void RotationVector(const VECTOR_3D t);

};

//Base class for all visible entities. Abstract. Concrete class should implement Render method.
class VISIBLE_ENTITY_BASE : public ENTITY_BASE
{

protected:
//todo what do we need to keep here as far as textures etc?
VECTOR_3D color;
GEOMETRY_BASE* geometry;

public:
virtual void Render()=0;
VECTOR_3D Color();
void Color(const VECTOR_3D t);

};

//Implementation of the game floor entity. Concrete.
class FLOOR: public VISIBLE_ENTITY_BASE
{
private:
static char* textureName;

public:
FLOOR();
~FLOOR();
void Render();
};

typedef float SCALAR;

// A 3D vector
class VECTOR_3D
{
public:

SCALAR x,y,z; //x,y,z coordinates

public:

VECTOR_3D();
VECTOR_3D( const SCALAR& a, const SCALAR& b, const SCALAR& c );

SCALAR& operator [] ( const long i );
const bool operator == ( const VECTOR_3D& v ) const;
const bool operator != ( const VECTOR_3D& v ) const;
const VECTOR_3D operator - () const;
const VECTOR_3D& operator = ( const VECTOR_3D& v );
const VECTOR_3D& operator += ( const VECTOR_3D& v );
const VECTOR_3D& operator -= ( const VECTOR_3D& v );
const VECTOR_3D& operator *= ( const SCALAR& s );
const VECTOR_3D& operator /= ( const SCALAR& s );
const VECTOR_3D operator + ( const VECTOR_3D& v ) const;
const VECTOR_3D operator - ( const VECTOR_3D& v ) const;
const VECTOR_3D operator * ( const SCALAR& s ) const;
friend inline const VECTOR_3D operator * ( const SCALAR& s, const VECTOR_3D& v ) { return v * s; }
const VECTOR_3D operator / (SCALAR s) const;

const VECTOR_3D cross( const VECTOR_3D& v ) const;
const SCALAR dot( const VECTOR_3D& v ) const;
const SCALAR length() const;
const VECTOR_3D unit() const;

void normalize();
};

Paul McKenzie
May 13th, 2008, 11:58 PM
Please re-edit your post to use code tags. Your post is practically unreadable.

Also, please read this:

http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8

I don't know what a VECTOR_3D is.

Regards,

Paul McKenzie

myranalis
May 14th, 2008, 12:24 AM
I've added code tags as suggested and the header file for the Vector3D class to the original post. I've attached the relevant cpp files to this message. I'm using cygwin/opengl/glut for this.

souldog
May 14th, 2008, 02:47 AM
there are lots of things wrong with this code. Try fixing some of these first

1.
There are two declarations of the geometry pointer

first in


class ENTITY_BASE
{
protected:
GEOMETRY_BASE* geometry;


next in


class VISIBLE_ENTITY_BASE : public ENTITY_BASE
{

protected:
//todo what do we need to keep here as far as textures etc?
VECTOR_3D color;
GEOMETRY_BASE* geometry;


Get ride of the second one. The allocation of the geometry object in the constructor of FLOOR is setting the more derived geometry pointer.
The call to Scale is being called in the ENTITY base class and is attempting to use the invalid geometry pointer declared in that class, causing the segmentation fault

2.
Your base classes need to have virtual destructors

myranalis
May 14th, 2008, 02:56 AM
there are lots of things wrong with this code.

Of that I am woefully aware :( and I'm working on it! But getting rid of the extra geometry variable did the trick for this particular issue. Thank you so much for your help.

souldog
May 14th, 2008, 03:02 AM
you really need to add virtual destructors, if you don't then you are going to be in a world of pain

kempofighter
May 14th, 2008, 11:52 AM
VISIBLE_ENTITY_BASE* f = new FLOOR;
ENTITY_BASE* e = static_cast<ENTITY_BASE*> (f);

Take a look at this:
http://www.cplusplus.com/doc/tutorial/typecasting.html