Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issues with Partial Class Function Overrides in C++

Is there any issue with partially overriding a set of virtual functions defined by a base class?

My compiler provides the following warning:

overloaded virtual function "MyBaseClass::setValue" is only partially overridden in class "MyDerivedClass".

The classes look like this:

class MyBaseClass
{
public:
    virtual void setValue(int);
    virtual void setValue(SpecialType*);
}

class MyDerivedClass : public MyBaseClass
{
public:
    virtual void setValue(int);
}

The easy way to get rid of this warning is to use different names for the base functions, but I wanted to know if there was any compelling reason to fix this specific warning. I do not believe this violates the C++ standard. My guess is that it's to warn a programmer that they may have forgotten to implement the behavior for all possible input types. In our case, it is intentional to exclude some of the specific types.

Would you discourage suppressing this warning altogether?

like image 657
FP. Avatar asked Jan 13 '10 15:01

FP.


2 Answers

The override for setValue(int) hides setValue(SpecialType*) of the base class (see the C++ FAQ Lite), so if you try to call setValue(new SpecialType()) you will get an error.

You can avoid this by adding a using directive to the derived class that "imports" the overloads from the base class:

class MyDerivedClass : public MyBaseClass
{
public:
    using MyBaseClass::setValue;
    virtual void setValue(int);
};
like image 154
sth Avatar answered Oct 15 '22 09:10

sth


The warning is correct, it's called "name hiding". A variable of type MyDerivedClass cannot call setValue(SpecialType*).


Now I'm going to blatantly rip off someone else's blog:

Overloading and name hiding in C++

In a phone conversation with Brad last night, he told me about a strange problem he's encountered in his new C++ job. Granted, it's probably no big deal to people with extensive C++ experience, but to those of us who live in managed code worlds, this seemed strange.

In C++, when you have a class with an overloaded method (member function, whatever you want to call it), and you then extend and override that method, you must override all of the overloaded methods.

I understand the case where you have changed a method signature in a child class, thereby invalidating the established interface. In this case, though, it seems counterintuitive, since you're not changing the interface, but selectively overriding. Which is different.

For example:

class FirstClass
{
public:
        virtual void MethodA (int);
        virtual void MethodA (int, int);
};

void FirstClass::MethodA (int i)
{
    std::cout << "ONE!!\n";
}

void FirstClass::MethodA (int i, int j)
{
     std::cout << "TWO!!\n";
}

Simple class here with two methods (or one overloaded method). You want to override the two-parameter version, so you continue with the following:

class SecondClass : public FirstClass
{
public:
    void MethodA (int);
};

void SecondClass::MethodA (int i)
{
    std::cout << "THREE!!\n";
}

Now, when you use an instance of SecondClass, most Java or C# programmers might assume you can call:

int main ()
{
    SecondClass a;
    a.MethodA (1);
    a.MethodA (1, 1);
}

However, the second call won't work, since the two-parameter MethodA is not visible. You can get a pointer and up-cast to FirstClass, but your SecondClass instance doesn't inherit the non-overridden methods directly.

like image 42
eduffy Avatar answered Oct 15 '22 08:10

eduffy