4 Replies - 1312 Views - Last Post: 24 August 2010 - 07:49 PM Rate Topic: -----

#1 demosthenes2k8  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 93
  • Joined: 30-December 09

Static pointer to a base class

Posted 23 August 2010 - 10:19 PM

So in some code that I've been working on, we have some code that looks like this (greatly simplified, of course, but...)
class Base {
private:
	static Base* instance;
public:
	Base* getInstance();
};

class Derived : public Base {
public:
	void Func();
};



While working on the code we discovered that, prior to changing it to Base-Derived (before it was just Base), there were many lines of
Base* b = Base::getInstance()

However, these all have to be updated to Derived in order to use Derived's functions. The only option I could see was to use
Derived* d = (Derived*)Base::getInstance()

Is this a good idea, or will it cause problems in the future?

Is This A Good Question/Topic? 0
  • +

Replies To: Static pointer to a base class

#2 Elcric  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 100
  • View blog
  • Posts: 453
  • Joined: 02-May 09

Re: Static pointer to a base class

Posted 24 August 2010 - 08:20 AM

Hello demosthenes2k8,

Please show an example in real code. Are you asking about casting from a base type to its derived type? I am not clear on what you want to know.
Was This Post Helpful? 0
  • +
  • -

#3 demosthenes2k8  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 93
  • Joined: 30-December 09

Re: Static pointer to a base class

Posted 24 August 2010 - 11:24 AM

I just wanted to know if casting a static pointer of a base class to its derived class will cause problems. Unfortunately, that pretty much IS the real code.

class ProxyBase : public Team166Task {
	public:	
		ProxyBase(void) {
			wpi_assert(ProxyHandle==NULL);
			ProxyHandle = this;
	
			// Start the actual task
			Start((char *)"166ProxyTask", PROXY_CYCLE_TIME);
		}
		~ProxyBase(void);
		
		static ProxyBase *getInstance(void) {
			return ProxyHandle;
		}
		
		virtual int Main(int a2, int a3, int a4, int a5,
					int a6, int a7, int a8, int a9, int a10);
	private:
		/**
		 * @brief The single instance handle to ProxyBase.
		 */
		static ProxyBase* ProxyHandle;
		// ...Insert a crapload of functions and variables
};

class Proxy : public ProxyBase {
	// More functions and variables
};


And in all the other files that take the Proxy:

Proxy *proxy = (Proxy*)Proxy::getInstance();


This post has been edited by demosthenes2k8: 24 August 2010 - 11:45 AM

Was This Post Helpful? 0
  • +
  • -

#4 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 844
  • View blog
  • Posts: 2,334
  • Joined: 20-August 07

Re: Static pointer to a base class

Posted 24 August 2010 - 02:37 PM

View Postdemosthenes2k8, on 24 August 2010 - 05:19 AM, said:

So in some code that I've been working on, we have some code that looks like this (greatly simplified, of course, but...)
class Base {
private:
	static Base* instance;
public:
	Base* getInstance();
};

class Derived : public Base {
public:
	void Func();
};



While working on the code we discovered that, prior to changing it to Base-Derived (before it was just Base), there were many lines of
Base* b = Base::getInstance()

However, these all have to be updated to Derived in order to use Derived's functions. The only option I could see was to use
Derived* d = (Derived*)Base::getInstance()

Is this a good idea, or will it cause problems in the future?


Your Base class looks like its implementing the Singleton design pattern, Base::Instance() is almost certainly returning a pointer to an object whose concrete type is Base, in which case casting to Derived* is a very bad idea indeed; its undefined behaviour, simply because a Base object is not constructed as a Derived object. Its very unsafe for a Derived pointer to 'point to' a Base object - since you are telling the compiler to expose part of an interface which doesn't actually exist at runtime.

If you think about it, creating a Derived object allocates memory for a Derived object, and calls the Derived constructor - that memory also includes the Base object, and the Base constructor will have been run implicitly; In this situation, the cast is ok (dynamic_cast<> would be preferable), however that is probably not the case here.

On the other hand, a Base object will not have run the Derived constructor, nor will it have the additional memory allocated for any extra Derived class members. There's a chance that, at least in the interim, you might get it to appear to be working as you expected - but even if you do, it could only take a tiny innocent change later on to the size of the class or to the constructor for everything to fall over in a big heap.


I believe that you would be better off creating your new class as a wrapper for your singleton - implement it as a separate unrelated singleton (Not a derived class - usually singletons aren't designed to be derived from), or if you absolutely must derive from it, you want to make sure that everything is properly overridden; base class functions are virtual where they need to be, etc.

In order to reach the new singleton, you would call MyClass* MyClass::getInstance() instead of Base* Base::getInstance()

This post has been edited by Bench: 24 August 2010 - 02:59 PM

Was This Post Helpful? 0
  • +
  • -

#5 demosthenes2k8  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 93
  • Joined: 30-December 09

Re: Static pointer to a base class

Posted 24 August 2010 - 07:49 PM

Unfortunately, my problem is that this code is supposed to be part of a framework. The class marked ProxyBase is supposed to be managed by me and the framework team, while the class Proxy is supposed to be designed so that other groups can edit that one file. This is so that they can easily download updates to the framework without breaking their custom functions.
Are there any better alternatives than what I was attempting that would suit my needs?

EDIT: Never mind, I found a solution.

This post has been edited by demosthenes2k8: 25 August 2010 - 08:40 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1