Skip to main content
gamedev.net
🔒 Locked

Interesting Problem involving Classes...

Started by Prozak May 22, 2002 at 12:55 PM 10 replies 300+ views
Original Post
Prozak
Prozak
Hi all, ok, i''m gonna spit it out. I have an interesting problem. I have 2 classes, X & Y. They are exactly alike, all methods are the same, same variables, just internal code differs. There exists a "mediator", a class that stays between the application and X and Y. So: A ---> M ----> X ----> Y Now, what i want is to be able to call a method in X or Y with no speed penalties because it goes thru M. Also, I would like to have it so that if I change parameters in a method in one class, the other has to be immediately updated. So: If X.Hello (int) becomes X.Hello (double) then Y.Hello (int) will also have to become Y.Hello (double). I also want to add more classes to M, like X and Y, in the future. I want to be able to call these as transparently as I call X and Y. geez... i don''t know if any of this got through to you, but i hope someone out there can help me out on this one... Thanks,

[Hugo Ferreira][Positronic Dreams][]
"Somewhere, something incredible is waiting to be known."
- Carl Edward Sagan (1934 - 1996)

Fruny
Fruny
quote:

Now, what i want is to be able to call a method
in X or Y with no speed penalties because it
goes thru M.



You will have a speed penalty. Either due to the switch statement that does the dispatch, or due to the extra pointer indirection by using virtual member functions.

quote:

Also, I would like to have it so that
if I change parameters in a method in one class,
the other has to be immediately updated.



Use the search and replace feature of your editor,or define your functions with typedefs (or macros if you want to change the number of arguments). Given that overriden member functions must be redeclared in subclasses, there is no magic solution.


#define HELLO_ARGUMENTS int
// #define HELLO_ARGUMENTS int, double
void Hello( HELLO_ARGUMENTS )

typedef void goodbye_ret_t;
typedef int goodbye_arg0_t;
// typedef double goodbye_arg0_t;

goodbye_ret_t GoodBye( goodbye_arg0_t arg0 );


Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
cgoat
cgoat
quote:
Original post by pentium3id
I have 2 classes, X & Y. They are exactly alike,
all methods are the same, same variables, just
internal code differs.



Sounds like you want an abstract base class:


  
class Base
{
virtual Method1(int arg1, double arg2)=0;
virtual Method2(double arg1)=0;
};


Then you would derive X and Y from that:


  
class X : public Base
{
Method1(int arg1, double arg2);
Method2(double arg1);
};

class Y : public Base
{
Method1(int arg1, double arg2);
Method2(double arg1);
};


So if you change the Base class definition, this will force you to update all the classes derived from it. They are forced to have AT LEAST those methods defined in the base.

I''m not exactly sure how your "mediator" class is going to work, but what doing the above allows is that your mediator would deal with "Base" type objects (which are really X or Y objects). It keeps track of them using Base* pointers.

So you could have:


  
Base* objArray[3];
X obj1;
Y obj2, obj3;

objArray[0] = &obj1
objArray[1] = &obj2
objArray[2] = &obj3

objArray[1]->Method1(5, 2.3); // Calls method of obj2



Your mediator would maintain the objects similarly.

Hope this helped some.
intellibug
intellibug
this means that it is a "pure virtual" function/method. such function has no actual implementation ( = abstract base class), but every class derived from the base class MUST implement the method. oh, and cgoat''s example code is wrong, because of the missing "virtual" in the dervied classes. so it goes something like this:


class AbstractBaseClass
{
public:
virtual void method() = 0; //PURE VIRTUAL
};


class DerivedClass : public AbstractBaseClass
{
public:
virtual void method(); //MUST PUT A virtual HERE
};

void DerivedClass::method()
{
//...
}
Dean Harding
Dean Harding
quote:
Original post by intellibug
oh, and cgoat''s example code is wrong, because of the missing "virtual" in the dervied classes.



The general rule is "once virtual, always virtual". You don''t need to add the virtual keyword in derived classes (though adding it does increase readability, in my opinion).


codeka.com - Just click it.
Prozak
Prozak
I believe I can''t describe the problem correctly without
stating the context, so here goes:

I''m developing a game engine, which will use OpenGL or
Direct3D or any other future technology.
It is called Djin. If the programmer/user selects
one of the available renderers, the respective rendereer
class is used. My setup is, the application talks to the
djin class, which in turn talks to the renderer classes,
opengl and directx3d (COGL, CD3D).

So, the programmer selects a default renderer to be used:
djin.renderer=ogl;

then calls a standard call:
djin.backgroundcolor(255,255,255);

now, what i want is to be able to setup djin''s backgroundcolor method to point to whichever renderer class is used, hopefully
without using statics...

Ok, i hope you guys understood the point...


[Hugo Ferreira][Positronic Dreams][]
"Somewhere, something incredible is waiting to be known."
- Carl Edward Sagan (1934 - 1996)

Dean Harding
Dean Harding
What''s wrong with the base class/derived class method? Just have Djin as the base class, and derive COgl and CDirectX from it. Then in your initialization code, do this:

Djin *renderer = new COgl();

or:

Djin *renderer = new CDirectX();

as appropriate.


codeka.com - Just click it.
Prozak
Prozak
ok....

look at the following example:
CWindow *zeta = new CWindow;

if i dont had the "= new CWindow;" pice of code,
and start using zeta->methods will i be working upon
an unitilialized memmory pool?

Will "new" initialize zeta''s memmory space? is that it?

thanx,


[Hugo Ferreira][Positronic Dreams][]
"Somewhere, something incredible is waiting to be known."
- Carl Edward Sagan (1934 - 1996)

Dobbs
Dobbs
That should actually be "new CWindow();" not "new CWindow;", but you''re basically right - if you simply declare

CWindow *zeta;

you just have a pointer to garbage. Any attempts to use zeta by calling its methods or accessing its fields will crash the program. Calling

CWindow *zeta = new CWindow();

allocates space for zeta (that''s what new does) and calls its constructor (CWindow).

Topic Locked

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

Sign in to reply to this topic.