Overloaded Virtual Methods

This week I came by a new kind of bug that I’ve never had before, and is up the top of bugs I’ve came by when using CodeWarrior, the top still being invisible syntax.

Though I don’t think anything can top that, it can be hell if you have garbage at the end of a line, and you can’t see it when even though the compiler tells you something is wrong, luckily to solve that one, you just press a key or change someone on the same line and it makes it visible.

Anyways, this bug is caused by having overloaded pure virtual or virtual methods in a base class, but only implementing some of the them in the derived class.

It causes the compiler to not acknowledge any of the other overloaded functions, which you can end up spending a lot of time trying to solve if you’re not familiar with it.

The below code shows an example base class for causing this error.

class BaseClass
{
//
// Functions
public:
	//
	BaseClass()
	{
	}
 
	//
	virtual ~BaseClass()
	{
	}
 
	//
	virtual int Multiply( const int inValue1 )
	{
		return 2 * inValue;
	}
 
	//
	virtual int Multiply( const int inValue1, const int inValue2 )
	{
		return 2 * inValue1 * inValue2;
	}
};

 

If in the derived class you implement one of these, as shown below, and then try to access one of the other overloaded that are only implemented in the base, the error will happen, telling you something like there are no overloaded versions of that function that take that parameters you are giving.

//
//
class DerivedClass : public BaseClass
{
//
// Functions
public:
	//
	DerivedClass()
		:
		BaseClass()
	{
	}
 
	//
	int Multiply( const int inValue1 )
	{
		return 3 * inValue1;
	}
};
 
//
//
int Main()
{
	DerivedClass testClass;
	return testClass.Multiply( 2, 3 );
}

 

Now I’m sure I had use overloaded virtual functions before, so why was this happening now. So after a bit of searching I found out that only some compilers have support for this.

The reason the error occurs, is because the compiler generates a list of virtual function names to link to in the class. However, if it fails to find a function matching the name of what is being called, it will check the base.

Because we had overloaded only one of overloaded virtual functions, it ended its search in the derived class. And when it tries to associate the correct function call with the correct function, it notices that the function has a different number of parameters to that which is recorded in the list, and causes an error.

Now there is a way around it, you explicitly tell the compiler to use the functions listed in the base by use of the “using” keyword.

//
//
class DerivedClass : public BaseClass
{
//
// Functions
public:
	//
	DerivedClass()
		:
		BaseClass()
	{
	}
 
	//
	using BaseClass::Multiply;
 
	//
	int Multiply( const int inValue1 )
	{
		return 3 * inValue1;
	}
};
 
//
//
int Main()
{
	DerivedClass testClass;
	return testClass.Multiply( 2, 3 );
}

 

This will not error, since when the compiler is generating a list of functions, it will also include the Multiply functions in the base. The using keyword also has scope, so putting it in public will make the functions accessible outside the class.