覆盖派生类中的某些重载但不覆盖其他类

时间:2014-07-07 09:44:58

标签: c++ inheritance overloading virtual

我希望这可行:

template <typename T> class MyBaseClass
{
public:
    MyBaseClass();

    virtual ~MyBaseClass();

    void DoSomething(const T& myClass);  
         // Implemented in .cpp file

    virtual void DoSomething(int n, const T& myClass);  
                 // Implemented in .cpp file
};

class MyDerivedClass : public MyBaseClass<int>
{
public:
    virtual void DoSomething(int n, const int& myInt);  
                 // Implemented in .cpp file
};

......以及我的代码中的其他地方:

int i;
MyDerivedClass myClass;
myClass.DoSomething(i);

然而,它没有;相反,它无法编译错误说(在Visual C ++的情况下)

error C2660: 'int::DoSomething' : function does not take 1 arguments

...即使显然在基类中声明的DoSomething版本, 只接受一个参数。如果我用派生类中的两个参数重新定义DoSomething,那么错误就会消失。

我犯了什么微妙的C ++规则,并且有一种优雅的解决方法吗?

1 个答案:

答案 0 :(得分:2)

C ++中的方法隐藏了超类的所有方法,这些方法具有相同的名称。在你的例子中

virtual void DoSomething(int n, const int& myInt);
派生类阴影中的

void DoSomething(const T& myClass);

在基类中,因此在使用派生类型的对象时,后一种方法不可见。

这种行为与Java等其他语言完全不同,其中一种方法不会影响具有相同名称但签名不同的其他方法,并且最初可能会感觉有点反直觉。这样做的原因只是C ++的名称查找规则:一旦在作用域中找到了名称,就不会考虑其他作用域。在您的示例中,编译器在派生类中查找DoSomething(const T&),并停止在超类中查找更多方法。

有一个简单的补救措施:要使所有DoSomething方法再次可见,请在派生类中使用using指令:

using MyBaseClass<int>::DoSomething;

using指令通过将方法拉入派生类的范围,使得被遮蔽的方法再次可见。现在,名称查找将在派生类的范围内找到正确的DoSomething(int, const int&)方法。