从多个模板化基类派生时,“隐藏隐藏的虚函数”警告

时间:2018-09-26 09:59:39

标签: c++

假设以下代码:

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 {}
};

基本上,我有一个带有成员函数的模板化类,该成员函数采用模板类型的参数。派生类从具有两个不同类类型的基类派生,并覆盖其中之一的功能。

使用Clang编译器时,它将生成一个hides overloaded virtual functions警告,这实际上是在此处使用的,即在派生类中不需要Base2::func(float)

我知道通过在编译器标志后附加-Wno-overloaded-virtual可以使该警告静音,但是我不确定这样做是安全的,因为在其他情况下此警告可能是有效的。

在我的项目中,我有成千上万的这种情况(即,许多具有不同类类型的派生类)。是否对此有什么好的建议,这样就不会在这种情况下出现警告,而在其他情况下保留它?

2 个答案:

答案 0 :(得分:2)

安全的方法是使用using取消隐藏该方法:

class Derived : public Base1, public Base2
{
public:
    using Base2::func;
    void func(int) override {}
};

具有预期的效果,

Derived d;
d.func(4.2f); // call correctly Base2::func(float) and not Derived::func(int).

要使有意隐藏的警告消失,仍然有编译器特定的方式:

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
};

然后:

Derived d;
d.func(4.2f); // call Derived::func(int).

答案 1 :(得分:0)

在这种情况下,我实际上不会使用多重继承,因为仍然可以借助类型转换来调用Base2::func()(例如,将Derived *隐式或显式转换为{{1 }}),尽管它被隐藏并且不在Base2 *的范围内。

相反,我会做

Derived

,这意味着class Derived : public Base1 { private: Base2 base2; public: void func(int) override {}; }; 根本不在func(float)的范围内。只有Derived(或朋友)的成员函数才能调用Derived

这确实防止了从base2.func(some_float)Derived *的隐式转换(或从Base2 *Derived &的隐式转换)。我认为如果您需要这种隐式转换,那么您的设计就会被破坏,因为这也将允许(间接)为Base2 &的实例调用Base2::func()。一般情况下,如果您发现自己在设计中相互矛盾(想要X,但实现X却产生了不想要的效果Y),这可能表明...设计缺陷。