假设以下代码:
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
可以使该警告静音,但是我不确定这样做是安全的,因为在其他情况下此警告可能是有效的。
在我的项目中,我有成千上万的这种情况(即,许多具有不同类类型的派生类)。是否对此有什么好的建议,这样就不会在这种情况下出现警告,而在其他情况下保留它?
答案 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),这可能表明...设计缺陷。