Sign in to follow this  
PSS

[SOLVED]Using Derived Method from Base Class Method (C++)

Recommended Posts

I'm having difficulties implementing something: I want to create an entire application using only this : (NOTE: I really don't want this section of code to change)
#include "BaseClass.hpp"

class MyClass : public BaseClass
{
  //Override base class's DoSomething
  int DoSomething(){ printf( "DoSomething says: %d", 9 ); }
}Instance;



BaseClass.hpp should looks like this:
class BaseClass
{
public:
  BaseClass();
  static BaseClass*& GetInstance()
  { 
    static BaseClass* s_t = 0; ;
    return s_t;
  }
protected:
  virtual int DoSomething(){ return 0; };
private:
  static void CallDoSomething();
}



My current implementation of BaseClass.cpp :
BaseClass::BaseClass()
{
  GetInstance() = this;  //Setting the instance (potential problem?)
}
void BaseClass::CallDoSomething()
{
  GetInstance()->DoSomething();  //Problem here at least.
}



Now, the issue I'm having is, GetInstance()->DoSomething, calls the base class method, when I intended to call the MyClass. Is there a pattern to implement this? Is there an easier way to implement base class to give me the ability to derive from it and use it like shown in MyClass? Thanks, PSS EDIT: Typo [Edited by - PSS on October 16, 2008 6:39:49 PM]

Share this post


Link to post
Share on other sites
The easy way is to call DoSomething directly you don't need getinstance or if you really want to denote the polymorphism use this->dosomething.

Also is getinstance overloaded in myclass? It isn't in the code you posted. It will call the base class version and get you base class instance.

Share this post


Link to post
Share on other sites
Quote:
Original post by stonemetal
The easy way is to call DoSomething directly you don't need getinstance or if you really want to denote the polymorphism use this->dosomething.

Also is getinstance overloaded in myclass? It isn't in the code you posted. It will call the base class version and get you base class instance.


Thank you for the response,

I can't call DoSomething directly, because CallDoSomething is actually a DXUT callback function (OnFrameRender), so it has to be called and trigger the DoSomething method call.

get instance is NOT overloaded, and CallDoSomething is a static method within BaseClass. Get instance assures a singleton for the class (DXUT application wrapper)

I know that the header and MyClass implementation work (I have a framework which I am using as a reference, though I do not have the source code to view the implementation...hence my problem)

Share this post


Link to post
Share on other sites
[EDIT - Oops, ignore me, sorry]

This won't work:


BaseClass::BaseClass()
{
GetInstance() = this; //Setting the instance (potential problem?)
}


GetInstance() returns a temporary copy of the pointer, which then vanishes at the end of the function.

[Edited by - EasilyConfused on October 13, 2008 4:15:20 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by EasilyConfused
This won't work:


BaseClass::BaseClass()
{
GetInstance() = this; //Setting the instance (potential problem?)
}


GetInstance() returns a temporary copy of the pointer, which then vanishes at the end of the function.


Oh, right sorry, it returns a reference:


static BaseClass*& GetInstance()
{
static BaseClass* s_t = 0; ;
return s_t;
}



that was a typo, thanks.

To re-iterate, the implementation (BaseClass.cpp) is the only portion of code that I need to figure out, the rest is proven to work. Looking at MyClass and BaseClass.hpp, can anyone decipher BaseClass's implementation?

Share this post


Link to post
Share on other sites
Wait, what's going on here?

If you're using something like GetInstance(), you're strongly implying that you only ever want one instance of the Base class to exist. If there is only one instance, then it can only be one particular type, so why do you need polymorphism? And for that matter, why do you have a public constructor?

It sounds like 'GetInstance' is really 'GetMostRecentlyConstructedInstance', which is a very useless construct. It will also cause you no end of grief once you start worrying about stack-allocated versus heap-allocated instances.

(Also: constructors are not inherited, so the 'GetInstance() = this;' logic is not invoked when you construct a MyClass.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Wait, what's going on here?

If you're using something like GetInstance(), you're strongly implying that you only ever want one instance of the Base class to exist. If there is only one instance, then it can only be one particular type, so why do you need polymorphism? And for that matter, why do you have a public constructor?

It sounds like 'GetInstance' is really 'GetMostRecentlyConstructedInstance', which is a very useless construct. It will also cause you no end of grief once you start worrying about stack-allocated versus heap-allocated instances.

(Also: constructors are not inherited, so the 'GetInstance() = this;' logic is not invoked when you construct a MyClass.


Thanks for the reply,

The idea is to have a single instance of the BaseClass, initiated as a MyClass. What I've been trying to do is hide everything from the user, so that he can instantiate the framework using only this:


#include "BaseClass.hpp"

class MyClass : public BaseClass
{
//Override base class's DoSomething
int DoSomething(){ printf( "DoSomething says: %d", 9 ); }
}Instance;



DoSomething is called through a callback function inside of the implantation code for the BaseClass.

I've noticed that 'this' pointer in the BaseClass constructor has the type of MyClass when it is being assigned to the BaseClass instance using the GetInstance reference. Can I somehow use this so that calling DoSomething from the instance pointer will use the MyClass's DoSomething?

something like this:

//Assign BaseClass instance as MyClass
template <class CLA>
AssignFunc( CLA* Obj, BaseClass*& fvpInstance )
{
fvpInstance = static_cast<CLA>( Obj ); //Force it to stay as CLA?
}

BaseClass()
{
AssignFunc( this, GetInstance() );
}



Or something similar?

Thanks for all the help so far, and any to follow

Share this post


Link to post
Share on other sites
All nonsense. Classes define a type. The point of setting up classes is to be able to make instances of the type as needed. It doesn't gain anything to do all that class wrapping and then set it up so there is only one instance. You could just use free functions in a namespace. Further, if the user has to implement the derived class anyway, it's hard to see what the class' existence is accomplishing at all. Further, you aren't actually implementing any of the necessary logic to restrict creation of other instances anyway.

Give me some real names. What is a "BaseClass" really? What does "DoSomething" actually, conceptually, do? And what do you think is accomplished by doing any of this?

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
All nonsense. Classes define a type. The point of setting up classes is to be able to make instances of the type as needed. It doesn't gain anything to do all that class wrapping and then set it up so there is only one instance. You could just use free functions in a namespace. Further, if the user has to implement the derived class anyway, it's hard to see what the class' existence is accomplishing at all. Further, you aren't actually implementing any of the necessary logic to restrict creation of other instances anyway.

Give me some real names. What is a "BaseClass" really? What does "DoSomething" actually, conceptually, do? And what do you think is accomplished by doing any of this?


I think I have solved my problem, though I can't test it until I get home, so I'll answer your question for now and I'll reply again afterwards if I have more issues:

BaseClass is actually "DXApp", and DoSomething is actually OnFrameRender() ( or OnCreateDevice, OnDeviceLost, OnDeviceReset, OnFrameMove etc..).

The idea is to never have to deal with DX initializing code, so that is all within the DXApp's static lib. OnFrameRender is being called by the DXUT framework each frame through a static callback function named OnFrameRenderCallback.

OnFrameRender should be a virtual function, and it should call the user's derived class's OnFrameRender if it is available, otherwise it will use the DXApp class's implementation of OnFrameRender.



I have written this example to give you an idea of what's going on(though non-dx, it should give you an idea):

This is the ONLY code a user should have to write to use the library:

#include <iostream>
#include "BaseClass.hpp"

using namespace std;
class MyClass : public BaseClass
{
public:
MyClass() : BaseClass(){}
std::string SayHi()
{
return "HI FROM MY CLASS";
}
}SAYHI__;





What this does, is says Hi from MyClass. If the "SayHi" function was not defined within MyClass, "SayHi" would have been called from Base class:


NOTE: EVERYTHING BELOW THIS LINE IS NON USER CODE - My Framework
================================================================================


#ifndef _GUARD_BASE_CLASS
#define _GUARD_BASE_CLASS

class BaseClass
{
public:
virtual std::string SayHi(){ return "Hi from BASE"; }
static BaseClass*& GetInstancePtrRef()
{
static BaseClass* s_this = 0;
return s_this;
};
protected:
BaseClass();
};

#endif





The rest of the implementation would go inside a static library and this is an example of what it would look like:

#include <iostream>
#include <string>
#include "BaseClass.hpp"

BaseClass::BaseClass()
{
//Set the instance
if( !GetInstancePtrRef() ) //Ensure a single instance
GetInstancePtrRef() = this;
}

int main()
{
//An instance is already created in MyClass.cpp
if( BaseClass::GetInstancePtrRef() )
std::cout << BaseClass::GetInstancePtrRef()->SayHi() << std::endl;
}





You can slap this code in a compiler, it compiles and runs.

This implementation seems far from useful, though when it comes to DX initializing code, you want to get as much of that hidden away as possible without removing too much from it's functionality (DXUT is still fully accessible, and a device can be recreated the long way by the user if required). This design also insures that DX can only be initialized once

Thanks again for the assistance.

Share this post


Link to post
Share on other sites

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