[C++] Inheritance & overloading

Started by
5 comments, last by Cowboy Coder 17 years, 1 month ago
Hello! I've had a simple problem in C++ with mixing inheritance and function overloading. I was just wondering if there were any workarounds. I have those two classes :

class DisplayContext
{
public:
	virtual CryoBool create(const DisplayContextStyle & in_style);
	CryoBool create(const Size & in_size, CryoBool in_fullscreen = CryoTrue);
};

class RenderContext : public DisplayContext
{
public:
	// Overloaded
	CryoBool create(const DisplayContextStyle & in_style);

};

The thing is, for some reason having only one of the two overloads virtual causes trouble to the compiler. The problem occurs when I do :
RenderContext rc;
rc.create(Size(800,600), CryoFalse);
The compiler outputs an error, saying that "create" does not take two arguments. So I have to do this :
rc.DisplayContext::create(Size(800,600), CryoFalse);
Which works, but which is ugly. Anyone knows why I'm getting this problem and if there's a simple solution?
Advertisement
I would introduce the original overloaded function into the derived class, with using:

class RenderContext : public DisplayContext{public:	// Overloaded	CryoBool create(const DisplayContextstyle & in_style);	using DisplayContext::create;};
oh thank you!

I didn't know how to use "using" for something else than namespaces!

I don't really understand why I have to do this however. It seems to me that this should have been the default behaviour.
You comment says //Overloading, but you are actually //Overriding. When you override a function in a subclass it hides the functions with the same name in the base class.
Quote:Original post by Trillian
oh thank you!

I didn't know how to use "using" for something else than namespaces!

I don't really understand why I have to do this however. It seems to me that this should have been the default behaviour.


This is due to the way C++ performs lookups. It first looks after a function by name, and only then looks for overloads of that function using its fully qualified name.

In your case, it looks for the function first in the class RenderContext, where it finds RenderContext::create. This interrupts the first stage of the search (looking for a function with that name) and starts the second stage, which looks for a two-argument overload. Obviously, RenderContext::create has no such overload, and so it fails. Since the first stage found one function with that name in the derived class, it never moves on to the base class.

The using directive introduces a function into a given namespace or class, so DisplayContext::create becomes accessible in RenderContext as RenderContext::create, so the overload is available when you look for it in the second stage.
It was the default behavior UNTIL the derived class messed with part of the set of things with the same name. Its a little similar to getting automatic copy-contructor, assignment operator, default, etc. UNTIL you do something to cause the compiler to assume you want to take control. In this case, because the compiler has no syntax for "removing" something from a base interface from the derived interface, it does this sillyness. Of course access to a RenderContext through a DeviceContext would have worked as expected.
Check the second question here for an explanation of the problem, and another solution:

http://msdn.microsoft.com/msdnmag/issues/02/05/c/

This topic is closed to new replies.

Advertisement