Sign in to follow this  

Inheritance problem

This topic is 4730 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got myself a small problem with inheritance, virtual functions, etc. And a few questions. So if you don't like helping people or answering questions, you don't actually need to read any further (though it may well be enlightening). Anyway, questions first. Lets say I have a base class, Module, and a child class GFXModule, like below.
class Module
{
	public:
		Module();
		~Module();
		virtual bool Initialize();
	private:
		HWND foo;
};

class GFXModule : public Module
{
	public:
		GFXModule();
		~GFXModule();
		virtual bool Initialize(HWND bar);
	private:
};

Now, how exactly would I go about calling Initialize, from a pointer like this: Module * theModule = new GFXModule;? Any time I try to do something like this: theModule->Initialize(someHWND); it won't compile, and will mention that I should use the 'Initialize()' function. So how would I go about calling the 'Initialize(HWND bar)' function? Secondly, regarding this problem, if we can go about calling that function, then, if we wanted to modify the HWND in the 'Module' class with it, would the function be defined something like this?
bool GFXModule::Initialize(HWND bar)
{
	Module::foo = bar;
}

Now, on to my second question, let's say that we have another function in the 'GFXModule' class, 'bool doThis(int x)', that does something. Now, how would we call that function from a pointer like the one in the earlier example? If I try to do something like 'theModule->doThis(2)' I get the following error: 'doThis' Undeclared, (first use the function) So, how do we call tat function with a pointer to 'Module'? Does it have to be included in 'Module' as a virtual function, and passed down? Because if things do have to happen like that, things are going to get a bit crowded, and, to me at least, it sort of defeats the purpose of inheritance and stuff.. Anyway, my thanks to all who take the time to look over this and answer my questions!

Share this post


Link to post
Share on other sites
your code needs to look something like this

class Module
{
public:
Module();
~Module();
virtual bool Initialize(HWND bar); // change is here
private:
HWND foo;
};

class GFXModule : public Module
{
public:
GFXModule();
~GFXModule();
virtual bool Initialize(HWND bar);
private:
};

Share this post


Link to post
Share on other sites
Module * theModule = new GFXModule;?

You might try making the pointer of the same type that you are making it point to...
GFXModule* theModule = new GFXModule;
that will allow you to call the inherited function of Initialize(HWND bar).

For the second part. You don't have to make a virtual function in the base class for inherited classes.

-edit-
You probably have to put
virtual bool Initialize(); this function into your inherited class or it might get linking errors.

Share this post


Link to post
Share on other sites
@mike25025: Yea, I figured I'd have to do something like that.. Thanks

@nprz:
Quote:

Module * theModule = new GFXModule;?

You might try making the pointer of the same type that you are making it point to...
GFXModule* theModule = new GFXModule;
that will allow you to call the inherited function of Initialize(HWND bar).

Unfortunately, I need it to be a pointer to 'Module' because, this is just an example, and not my full setup. You see, a module could be a GFXModule as it is here, OR, it could be a SoundModule, or a NetworkModule, or whatever.
Quote:

For the second part. You don't have to make a virtual function in the base class for inherited classes.

I don't exactly see how that is helping me? It doesn't answer my question, which was, how does one call the 'doThis' function? Or is it simply not possible with only a pointer to 'Module'? If such is the case, then I may have to do a bit of design re-thinking :/

Oh, also, one last question, that just occurred to me. Let's say I have a few pointer, like:
GFXModule * foo
SoundModule * bar
InputModule * test
. Now, if all those classes inherited from 'Module', could I potentially make a function that returns a pointer to 'Module', and have it return one of those? Thanks

[EDIT] Whoa, managed to mess up BOTH my close-quote codes.. Bah

Share this post


Link to post
Share on other sites
A couple things.

As far as I know, if you have a virtual function, you need to create a matching function. For instance: You use
virtual bool Initialize();

Module * theModule = new GFXModule;

You need:
bool Module::Initialize(){};
Because you are not strictly creating a GFXModule you can get away with not having it in GFXModule, but it will come up to bite you later.

Next,
theModule->Initialize(someHWND);
is not defined for Module. For something like this, you would have to create a copy constructor and then do a cast (as far as I know). Such as:
GFXModule(const Module&){}; //In the GFXModule class
((GFXModule) *theModule).Initialize(someHWND); //I am fairly sure this is bad practise, but I don't have another way.


Next,
bool GFXModule::Initialize(HWND bar)
{
Module::foo = bar;
}
is wrong. foo is going to be different for every instance, so right there you know that you can't just contact it through Module. Next, because it is private (not shared with child classes), I don't think you can access it at all (properly). As far as I can remember, you want to instead make it
protected:
, and then put
bool GFXModule::Initialize(HWND bar)
{
this->foo = bar;
}


For your last question, if it is a function from a child class, you would have to cast to that child class before you can call it. That is because it is not defined for module. Then, yes, you would call it
whatever->doThis(2)


Quote:
Now, if all those classes inherited from 'Module', could I potentially make a function that returns a pointer to 'Module', and have it return one of those?
Yes, you could do that. It should be just as straightforward as it sounds.

Hope that helps some.

Share this post


Link to post
Share on other sites
Its really no problem. I like this sort of thing.

Oh, and one other thing.
((GFXModule) *theModule).Initialize(someHWND);
I forgot to mention that when you do something like this, it is making a temporary copy of theModule to use the function from. You have to remember that because it is a temporary instance being acted on, if you try to set any variables in the Initialize(HWND) function, they will not be set for theModule. In that case, you would want to keep a temporary copy of GFXModule you create, do whatever you want with it, and then copy back the vaariables from it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
No need at all to "open" the pointer and the copies etc...
Just do this:
[CODE]
((GFXModule*) theModule)->InitModule(someHWND);
[/CODE]

Share this post


Link to post
Share on other sites
Or, the typesafe and C++ way:

if(GFXModule* thisModule = dynamic_cast<GFXModule*>(theModule))
thisModule->InitModule(someHWND);

The problem with a C-style cast like this:

((GFXModule*) theModule)->InitModule(someHWND);

is that it will attempt to cast, and devil take the consequences - it's up to the programmer to ensure you're casting to the right thing. A dynamic_cast will 'fail' (compiler defined, I believe - such as return NULL) if the object being cast to isn't actually that type i.e. in the example above, if you try and dynamic_cast to something that isn't actually a GFXModule* it will never get to result part of the 'if' statement.

Jim.


Share this post


Link to post
Share on other sites
You could pass some relevant context which will be useful to all the modules.

The context would allow them to get the information they needed to be created correctly.

The context could be something like:


class ApplicationContext {
public:
HWND GetWindow();
SoundLevels& GetSoundLevels();
KeyboardMapping GetKeyboardMapping();
//etc.
};


and the modules would use it like

class Module {
virtual void Initialise(ApplicationContext& context);
};

class SoundModule : public Module {
public:
virtual void Initialise(ApplicationContext& context) {
SoundLevels levels = context.GetSoundLevels();
//use sound levels to initialise etc.
}
};
//etc.



So you would use this like:

#include "ApplicationContext.h"
#include "Module.h"
#include "SoundModule.h"

int main() {
ApplicationContext context;
Module* mod = new SoundModule;
mod->Initialise(context);//calls context.GetSoundLevels()
return 0;
}



An alternative is to use the constructor or an initialiser function whilst you know the type of the module, e.g.


int main() {
SoundLevels levels;
SoundModule* SMod = new SoundModule(levels);
//or
SMod->Initialise(levels);//Initialise isn't virtual
return 0;
}

Share this post


Link to post
Share on other sites

This topic is 4730 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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