Reputation: 459
Suppose the code below:
Base.h
template <class T>
class Base
{
public:
virtual void func(T value) {}
};
Derived.h
class Derived : public Base<Type1>
, public Base<Type2>
{
public:
void func(Type1 object) override {}
};
Basically I have a templated class with a member function that takes the argument of the template type. The derived class derive from the base with two different class type, and override the function of one of them.
With the Clang compiler, it would generate a hides overloaded virtual functions
warning, which is actually intended here, i.e. I do not need Base2::func(float)
in the derived class.
I am aware that by appending -Wno-overloaded-virtual
to the compiler flags would mute this warning but I'm not sure that's the safe thing to do, as in other cases this warning may be valid.
In my project I have thousands of this case (i.e. many derived classes with different class types). Are there any good suggestion over it so the warning wouldn't be present for this situation but keep it for others?
Upvotes: 2
Views: 7771
Reputation: 36617
I actually wouldn't use multiple inheritance in this case, since it is still possible to call Base2::func()
with the help of a type conversion (e.g. convert Derived *
implicitly or explicitly to a Base2 *
), despite it being hidden and not in scope of Derived
.
Instead, I would do
class Derived : public Base1
{
private:
Base2 base2;
public:
void func(int) override {};
};
which will mean that func(float)
is not within the scope of Derived
at all. Only member functions of Derived
(or friends) would be able to call base2.func(some_float)
.
This does prevent implicit conversion of a Derived *
to a Base2 *
(or Derived &
to a Base2 &
). I'd argue that if you need such implicit conversions, then your design is broken, since that would also permit (indirectly) calling Base2::func()
for an instance of Derived
. Which, presumably if you want it hidden, you wish to avoid ...... Generally speaking, if you find yourself in a contradictory discussion in design (you want X, but achieving X has an unwanted effect Y) that's a sign of a design flaw.
Upvotes: 0
Reputation: 217970
The safe way is to unhide the method is with using
:
class Derived : public Base1, public Base2
{
public:
using Base2::func;
void func(int) override {}
};
With that following works as expected:
Derived d;
d.func(4.2f); // call correctly Base2::func(float) and not Derived::func(int).
To silent the warning for intentional hiding, there are still the compiler specific way:
class Derived : public Base1, public Base2
{
public:
#pragma clang diagnostic push
# pragma clang diagnostic ignored "-Woverloaded-virtual"
void func(int) override {}
#pragma clang diagnostic pop
};
And then:
Derived d;
d.func(4.2f); // call Derived::func(int).
Upvotes: 3