Question

CallingClass::CallingFunc()
{
    SomeClass obj;
    obj.Construct(*Singleton::GetInstance()); // passing the listener
    // Singleton::GetInstance() returns a static pointer.
    //Singleton is derived from IListener
}

SomeClass::Construct(const IListener &listener)
{
    IListener* pListener = const_cast<IListener*>(&listener);
}

After const_cast pListener is null. Is it possible to perform such typecasting?

Thanks

Was it helpful?

Solution

Two questions:

  1. What are you trying to acheive here?
  2. How much control have you got over the code? (i.e. what are you able to change?)

Without wishing to be unkind I would honestly say that it might be better to start again. There are a couple of issues I would have with this code:

Firstly, the Singleton pattern should ensure that only one of a specific object is ever created, therefore it is usually returned by pointer, reference or some derivative thereof (i.e. boost shared pointer etc.) It need not necessarily be const though and the fact that it is here indicates that the author did not intend it to be used in a non-const way.

Second, you're then passing this object by reference into a function. No need. That's the one of the major features (and drawbacks) of the singleton pattern: You can access it from anywhere. So you could just as easily write:

SomeClass::Construct()
{
    IListener* pListener = const_cast<IListener*>(*Singleton::GetInstance());
}

Although this still doesn't really help you. One thing it does do is make your interface a bit clearer. You see, when you write SomeClass::Construct(const IListener&listener) anyone reading your could reasonably imply that listener is treated as const within the function and by using const_cast, you've broken that implied contract. This is a very good reason that you should not use const_cast - at least not in these circumstances.

The fundamental question that you need to ask yourself is when your IListener is const, why do you need to use it in a non-const way within Construct? Either the singleton should not return a const object or your function should not need it to be non-const.

This is a design issue that you need to sort out before you take any further steps.

OTHER TIPS

So let me see. You have two-phase initialization, a Singleton, and casting away const, and you're de-referencing an object just to take it's address again? A stray NULL pointer is the least of your concerns, my friend.

Throw it away and write it again from scratch. And pick up a C++ book first.

Just so you know, const_cast cannot produce a null pointer unless it was passed one. GetInstance() must be returning NULL to produce this behaviour, which is formally UB as soon as you de-reference it.

const_cast is basically an instruction to the compiler to ignore the constness of something. Use of it is to be avoided, because you are overriding the compiler protection, and it can lead to a crash as you write something that attempts to update read-only memory.

However, it doesn't actually cause any code to be generated.

Therefore, if this:

IListener* pListener = const_cast<IListener*>(&listener);

results in pListener being NULL, then &listener is NULL, which is impossible (or you are returning a null reference for your singleton, or you are missing something out from your description of the problem).

Having said which I agree strongly with the answer from DeadMG.

Creating an empty object and doing an Init on it (2-phase construction) is to be avoided. Properly created objects should be valid, and if you have an Init method, it isn't.

Removing the constness from anything is to be avoided - it is extremely likely to produce surprising behaviour.

The amount of de-and-rereferencing in that code is going to give anyone a headache.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top