Why can't I override inherited function?

2020-07-30 03:36发布

问题:

When I tried to compile next construction I have got the error: cannot convert parameter 1 from 'std::vector<_Ty>' to 'float' Why dose it happen?

class A
{
public:
    virtual int action(float)
    {return 5;}

    virtual int action(std::vector<float>)
    {return 10;}
};

class B : public A
{
public:
    int action(float) override
    {return 6;}
};

class C : public B
{
public:
    int action(std::vector<float>) override
    {
       B::action(std::vector<float>());
       return 7;
    }
};

int main()
{
   C instance;
   int temp = instance.action(std::vector<float>());
   getchar();
   return 0;
}

回答1:

When the compiler sees a function call

B::action(std::vector<float>());

It needs two steps to decide which function call needs to be made. In the first step it looks up the name action. If the lookup results in one or more functions, it stops the lookup. It does not lookup the overloaded functions in base classes. If the lookup results in multiple function names, it tries overload resolution.

In your case, the lookup results in only one function - int B::action(float). The lookup stops there. However, that function does not match the argument being used. Hence, the compiler reports it as an error.

I can think of the following ways to resolve the problem.

Make all overloads of A::action available for lookup in B

class B : public A
{
   public:
      using A::action;
      int action(float) override
      {return 6;}
};

Change the call so it uses A::action(float)

class C : public B
{
   public:
      int action(std::vector<float>) override
      {
         A::action(std::vector<float>());
         return 7;
      }
};

I strongly recommend using the first approach.



回答2:

The compiler does not search for overloads in parent classes if the derived class declares a function by the same name. Typically, if you've enabled warnings, the compiler would warn something like:

warning: 'C::action' hides overloaded virtual function [-Woverloaded-virtual]

If you specify the scope where the overload is declared, the call will work:

A::action(std::vector<float>());

But more generally, you should always avoid overloading virtual functions.



标签: c++