Code: Select all
if(!instance) instance = (SingletonInterface*)(new SingletonImplementation());
That downcast would have been done implicitly, so that isn't necessary. Also, I would recommend a static_cast, if you insist on doing it explicitly.
short wrote:instance is of type SingletonInterface, not SingletonImplementation. It's true type is SingletonImplementation, but it is being stored as SingletonInterface. Your SingletonImplementation function "definition" isn't being optimized out, it's being ignored because instance is being stored as the interface type. When you call a method on it, it's using the type defined by the interface, not the implementation.
Wrong. That's the entire point of a virtual function. It should still invoke the child function even though you are referencing it through the parent.
I have a theory as to what is happening...
You code looks polymorphically correct. I would be expecting the same behavior that you are. However, you brought up an interesting point:
she wrote:This is supported by the fact that when I remove the const-ing from the functions of both SingletonInterface and SingletonImplementation, everything works the way I would expect it to, e.g. SingletonImplementation functions are invoked.
You really should have mentioned this in your first post.
she wrote:What could it be about const-ing these functions that's screwing me up?
Nothing, which is what leads me to believe that it's a compiler-error.
Your iAreNotWorking() method is being implicitly declared inline within the parent class. By adding the const, I am almost positive that it is getting immediately inlined without the compiler bothering to look at the virtual table... thus breaking polymorphism.
If you take a moment to think about that function from the optimizer's perspective, it makes sense. Without the "const," it cannot be sure that you aren't modifying members of the child type. So inlining would not be an option. WITH the "const," you are guaranteeing that no member variables are being modified... so it is safe to inline.
In Conclusion
1) Set a breakpoint within SingletonInterface::iAreNotWorking(). You can't, can you? It has been inlined.
2) Move your implementation of SingletonInterface::iAreNotWorking() to your .cpp file. This will prevent the compiler from even having the option of inlining it. Should you have to do this? No. It's a compiler bug. But this is a valid work-around.
OR
2.5) Turn off compiler optimizations for that one file.
3) Come back and tell me how right I was.