Skip to main content
GameDev.net gamedev.net
🔒 Locked

Inhearitence problems... (functions)

Started by Destroyer Dec 30, 2001 at 9:45 AM 13 replies 600+ views
Original Post
Destroyer
Destroyer
Hi, Here''s my problem I''ve got a class called CMovSurface, and it inhearates from a class called CSurface. I have a function in CMovSurface like this one below:
  

int CMovSurface::Check_For_Collision(CSurface *checksurface)
{
	RECT intersectrect;
	
	RECT checkrect;
	RECT movrect;

	SetRect(&checkrect, checksurface->x, checksurface->y, (checksurface->x + checksurface->width), (checksurface->y + checksurface->height));
	SetRect(&movrect, x, y, (x + width), (y + height));
	
	IntersectRect(&intersectrect, &checkrect, &movrect);

	return(0)
}

  
Of course it''s not complete - but that''s not my problem. The problem here occurs when I try to access the protected members x, y, width, and height of the CSurface class. I want to acess them, but I don''t want to have to make those members public either. Isn''t there a way to access those members since CMovSurface is inhearating from CSurface... Any help, Thanks, Eric //---------------------------- In a world without boundaries - who needs gates or windows ? ----------------------------\\
DarkEmpire
DarkEmpire
Hi,

You can use inline functions to access the members of your CSurface class.

ex:
inline int Width()
{
return Width;
}


By inlining function, there is no additionnal cost for the call of the function.
QWERTY
QWERTY
If a class CSurface is a parent class of CMovSurface and members x, y, width and height are declared in CSurface as protected, they are actually visible only for classes inherited from CSurface. They are not public. This mean they are not accessible from outside this class. If you don''t want them to be accessible from inherited classes, declare them as private. I hope it''s clear now.
mbulow
mbulow
Hi

No offence but are you 100% sure that the variables are NOT private instead of protected???

As far as I can remember there should be NO problem accessing base-class variables as long as they are NOT private

REMEMBER: No access specifier, makes vars and funcs private

BTW: Maybe it could help if you posted the CMovSurface class-definition
Caesar
Caesar
The problem could be also that when you''ve inherited the class, you did like

class X:protected Y{
}

instead of

class X:public Y{
}

the first pushes the Y class members one step up in the "security system"

hope that helps
Destroyer
Destroyer
Uhh... sorta what I''m asking...

I know how inhearitence works, that''s not the problem, the problem is the inhearited class (CMovSurface) has a member function that has been passed its parent class. However, the member function can''t acess the members in the parent class. I don''t want to make funcs like GetXPos() and GetYPos, etc. There''s gotta be a way around this...

Here''s CMovSurface

  
#include "CSurface.h"
#include "CVectSurface.h"

#define COLLISION_TOP 0
#define COLLISION_BOTTOM 1
#define COLLISION_RIGHT 2
#define COLLISION_LEFT 3
#define COLLISION_TOP_RIGHT 4
#define COLLISION_TOP_LEFT 5
#define COLLISION_BOTTOM_RIGHT 6
#define COLLISION_BOTTOM_LEFT 7

#ifndef CMOVSURFACE
#define CMOVSURFACE

class CMovSurface : public CSurface
{
HRESULT Move_Surface(DWORD starttime);

int Check_For_Collision(CSurface* checksurface);
int Check_For_Collisions(CVectSurface* checksurfaces);
int Check_Pixel_by_Pixel_Collision(CSurface* checksurface, int bpp);
int Check_Pixel_by_Pixel_Collisions(CVectSurface* checksurfaces, int bpp);

protected:
int xv;
int yv;
};

#endif CMOVSURFACE



and here''s CSurface

  

#include <ddraw.h>
#include <windows.h>
#include "ISurface.h"
#include "CMovSurface.h"

#ifndef CSURFACE
#define CSURFACE

class CSurface : public ISurface
{
public:

HRESULT Init(POINT startpos, int widthofwindow, int heightofwindow, HWND windowhandle, char* bmpname, LPDIRECTDRAW7 lpdd, int mode); // mode Set to DDSCAPS_VIDEOMEMORY or DDSCAPS_SYSTEMMEMORY

HRESULT Init(int widthofwindow, int heightofwindow, HWND windowhandle, char* bmpname, LPDIRECTDRAW7 lpdd, int mode); // mode Set to DDSCAPS_VIDEOMEMORY or DDSCAPS_SYSTEMMEMORY

virtual HRESULT Release(void);

HRESULT Set_Coordinates(int xpos, int ypos);

HRESULT Set_Surface_Src_Rect(RECT bmpsrcrect);
HRESULT Set_Scaled_Dest_Rect(RECT bmpdestrect);
HRESULT Toggle_Hide_Surface(void);

//bool Wait_Time(DWORD waitingtime);


bool Check_Current_Src_Rect(RECT checkrect);

virtual HRESULT Draw_Surface(LPDIRECTDRAWSURFACE7 dest);

friend int CMovSurface::Check_For_Collision(CSurface *checksurface);

protected:

int x; // x pos

int y; // y pos


int width; //width

int height; //height


int swidth; //Stretch width paramaters

int sheight; //Stretch height parameters


bool stretched;

bool hidden;

POINT srcpos; //holds the position on the bitmap for where to blit from


/* DWORD prevtime;
bool waiting;*/

};
#endif CSURFACE


Any ideas?

Thanks

Eric

//----------------------------
In a world without boundaries -
who needs gates or windows ?
----------------------------\\
QWERTY
QWERTY
Well, if the class CMovSurface is inherited from CSurface you do not need to declare CMovSurface::Check_For_Collision(CSurface *checksurface) method in CSurface as friend. Class CMovSurface already has access to all protected members of it''s parent class. Why couldn''t you access members of parent class. In the code you gave here, they are declared as protected. So you can access them from inherited class and they are not accessible from outside of the class. I''m afraid, but I still don''t know what your problem is.
LordKronos
LordKronos
Well, this is a strange problem. I tried your code (with slight modification) and it seems I might have learned something I never realized. It appears that while a child class can access its parent class''s protected member in its own instance, it cant access them in another instance. For example, in Check_Pixel_by_Pixel_Collision, I can do:

printf("x:%d y:%d w:%d h:%d\n", x, y, width, height);

but not

printf("x:%d y:%d w:%d h:%d\n", checksurface->x, checksurface->y, checksurface->width, checksurface->height);

That doesnt seem right to me. I''ll have to figure our whats going on here.
Ron FrazierKronos Softwarewww.kronos-software.comMiko & Molly - Taking Puzzle Games to A Whole New Dimension
LordKronos
LordKronos
Well, from what I can tell, you either do one of the following:


1)Make CMovSurface a friend,


class CSurface : public ISurface
{
friend class CMovSurface
//other stuff here
};


2) the variables public
3) public accessor methods for the variables
4) some other public method like like

FillRect(RECT& rect)

which you could then call as

checksurface->FillRect(rect)

5) make a method in the base class (CSurface) to acess the other objects variables or to fill in the RECT. For example:

int getSurfaceX(CSurface* surface)
{
return surface->x;
};

which you could then call from CMovSurface like

getSurfaceX(checksurface);

notice I didnt do checksurface->getSurfaceX(); The advantage of this last method is that you can declare these methods as protected but still access them because you will be calling the methods in your own instance, but those methods will work on the other instance. The reason this method can get away with accessing the protected members of the other instance is because the function that accesses the other instance is defined in the base class (CSurface) and it is always implied that a class is friends with itself (then thing work the same way as option 1...making CMovSurface a friend of CSurface)

All in all, I think I personally prefer option 3 or 5 the best. Option 3 is probably preferred, but if you are insistant on not allowing other classes to see the CSurface''s x,y,width,height, etc. for some reason, then go with option 5. If you go with option 3, remember that these accessor method will allow other classes to see x,y,width,height,etc... but no set them. I dont see how this hurts anything. On the other hand, if you want CMovSurface to be able to set these properties too, then I could maybe understand why you wouldnt want other classes to have this kind of access, so option 5 works good here

Hope this post isnt confusing or anything.

Ron FrazierKronos Softwarewww.kronos-software.comMiko & Molly - Taking Puzzle Games to A Whole New Dimension
Pactuul
Pactuul
LordKronos - that is right, why would it not? Your passing a pointer to the function of type csurface, the x,y,z in that class are protected like we established. of course if you access those from outside that instance you CAN'T get to the x,y,z...You can only access info from your instance if it's private or protected...

That's why this doesn't work:

  SetRect(&checkrect, checksurface->x, checksurface->y, (checksurface->x + checksurface->width), (checksurface->y + checksurface->height));  


because your accessing another instances protected members, that's a no-no

and this does work:

  SetRect(&movrect, x, y, (x + width), (y + 
height));


because it is accessing our instance members which we can do...

Simple

Pac

"The thing I like about friends in my classes is that they can't access my private members directly."
"When listening to some one tell about their problem (whether it's code or not), don't listen to what went right or wrong, but what they assumed....."





Edited by - Pactuul on December 31, 2001 8:56:56 AM
-Pac "The thing I like about friends in my classes is that they can't access my private members directly." "When listening to some one tell about their problem (whether it's code or not), don't listen to what went right or wrong, but what they assumed....."
Destroyer
Destroyer
Hi,

Thanks, Oh well, I was hoping there was someother "special" way that I missed when learning the language... Oh well. I''ll probably do a function like CSurface::Get_Rect() type thing. I guess that''ll be the smartest thing to do, if I want to make more inhearited classes like from CMovSurface, I don''t wanna have to make it a friend class each time into CSurface...

Thanks a lot!


Eric

//----------------------------
In a world without boundaries -
who needs gates or windows ?
----------------------------\\
LordKronos
LordKronos
quote:
Original post by Pactuul
LordKronos - that is right, why would it not?


Well, yes, once I figured out what was happening, it started to make sense, but because Ive never tried to do this in my code I didnt realize such a limitation exists. You can access another instances protected members, but only if the code to access them is in the same class, but not a descendant class.

I consider myself to be VERY knowledgeable wrt OOP, but my understanding of protected (from the half-a-dozen books and dozens of web sites I''ve read on the topic) was that "any and all rights to protected members in a base class get passed on to child classes". What it REALLY seems to mean is "any and all rights to protected members OF A CLASSES OWN INSTANCE in a base class get passed on to child classes". I''ve NEVER seen this documented anywhere. Admittedly, I havent read the C++ specification...Im not personally very big on reading specs. But thats the danger of learning from someone else (a 3rd party author)...you only get told what they remember (or care) to tell you. So noone to blame but myself. However, this scenario is kind of a subtle aspect that doesn''t come into play too often, so I could imagine most of the authors of those books might not even know about this technicality.

OK, I think Im done blabbering on about my own ignorance now

Ron FrazierKronos Softwarewww.kronos-software.comMiko & Molly - Taking Puzzle Games to A Whole New Dimension
Stoffel
Stoffel
This is weird, though. This code compiles:
  
class Base
{
protected:
int n;
};

class Derived : public Base
{
public:
void Foo (Derived &arg) { ++arg.n; } // arg is derived

};

..but this doesn''t:
  
class Base
{
protected:
int n;
};

class Derived : public Base
{
public:
void Foo (Base &arg) { ++arg.n; } // arg is now base

};

News to me.
thuned
thuned
quote:
Original post by Stoffel
This is weird, though. This code compiles:

    
class Base
{
protected:
int n;
};

class Derived : public Base
{
public:
void Foo (Derived &arg) { ++arg.n; } // arg is derived

};

..but this doesn''t:

class Base
{
protected:
int n;
};

class Derived : public Base
{
public:
void Foo (Base &arg) { ++arg.n; } // arg is now base

};

News to me.

i don''t know too much about this but if your first example, you are inside the Derived instance itself, so you can safely access the protected member. in the 2nd one, you recieve a "foreign" parameter that''s not a part of your own instance, so you can''t access the protected member.
life is unfair, take advantage of it.UNMB2 - if the link doesn't work, try clicking it :)
Pactuul
Pactuul
Good Grief people!

That''s not te reason it doesn''t work with Base, but with Derived.... Here''s a quote I found on some forum a long time ago:

[qoute]A derived class can only access a protected member of a
base class using a pointer or reference to the derived class,
otherwise one could violate type safety by messing up sub-objects of other derived classes. [/qoute]

-Pac "The thing I like about friends in my classes is that they can't access my private members directly." "When listening to some one tell about their problem (whether it's code or not), don't listen to what went right or wrong, but what they assumed....."

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.