Warning: overloaded virtual function “Base::process” is only partially overridden in class “derived”

我的梦境 提交于 2020-08-01 12:53:37

问题


I am getting below warning . part of my code is :

class Base {
public:
    virtual void process(int x) {;};
    virtual void process(int a,float b) {;};
protected:
    int pd;
    float pb;
};

class derived: public Base{
public:
    void process(int a,float b);
}

void derived::process(int a,float b){
    pd=a;
    pb=b;
    ....
}

I am getting below warning :

 Warning: overloaded virtual function "Base::process" is only partially overridden in class "derived"

any way i have made process as virtual function so I am expecting this warning should not come ... What is the reason behind this ??


回答1:


The reason for the warning

Warning: overloaded virtual function "Base::process" is only partially overridden in class "derived"

is that you haven't overridden all signatures, you have done it for

virtual void process(int a,float b) {;}

but not for

virtual void process(int x) {;}

Additionally, when you don't override and don't use using Base::process to bring functions to scope the static calls to derived::process(int) won't even compile. This is because Derived has no process(int) at that case. So

Derived *pd = new Derived();
pd->process(0);

and

Derived d;
d.process(0);

won't compile.

Adding using declaration will fix this enabling for static call to hidden functions through pointer to Derived* and select operator d.process(int) to compile and for virtual dispatch (call to derived through base pointer or reference) to compile with no warnings.

class Base {
public:
    virtual void process(int x) {qDebug() << "Base::p1 ";};
    virtual void process(int a,float b) {qDebug() << "Base::p2 ";}
protected:
    int pd;
    float pb;
};

class derived: public Base{
public:
    using Base::process;

    /* now you can override 0 functions, 1 of them, or both
    *  base version will be called for all process(s) 
    *  you haven't overloaded
    */
    void process(int x) {qDebug() << "Der::p1 ";}
    void process(int a,float b) {qDebug() << "Der::p2 ";}
};

now:

int main(int argc, char *argv[])
{
    derived d;
    Base& bref = d;
    bref.process(1);    // Der::p1
    bref.process(1,2);  // Der::p2 
    return 0;
}



回答2:


When you override a virtual method in a class, any overloads of that method that are not overridden are hidden for that class and cannot be used. So in your example, attempting to call process(int) on a derived object would fail because the overridden process(int, float) has hidden it.




回答3:


You have only overriden one of the two overloads of process. You are missing the overload taking only an int.

class Base {
public:
    virtual void process(int x) {;}; // You do *not* override this in derived
    virtual void process(int a,float b) {;}; // You do override this
// ...
};

Depending on what you want, you could:

  1. Simply override the int overload too in derived; or

  2. make the int overload nonvirtual and let it call the virtual int, float overload.

Two side notes: (a) Although most compilers accept it, a ; after a function body is syntactically wrong. (b) Protected member variables are generally frowned upon nearly as much as public ones; you should use protected getters/setters and make the variables private.




回答4:


C++ overload resolution.

Long story short, partial overriding an overloaded function can be weird when trying to resolve the name.

Also, from a design standpoint. the pattern is generally odd. I have a function that I've decided is the same enough to warrant the same name: in general, it is a tacit agreement that it does the same thing. When you change the behavior of a function in the child class, then, it is weird if it you only change part of it in derived. Essentially, its easy to read (using ~= as about equal)

//IMPLICIT STATEMENTS

1) Base::process(int) ~= Base::process(int,float)

2) derived::process(int) ~= derived::process(int,float)

//EXPLICITE STATEMENTS

3) Base::process(int) == derived::process(int)

4) Base::process(int,float) != derived::process(int,float)

essentially, since 3 and 4 are in conflict, then 2 can't possibly be true.




回答5:


When you declare a method with same name as one in Base, those methods are hidden.

It is the case when you override one method.

So

derived d;
d.process(42); // won't compile

To solve that: add using Base::process:

class derived: public Base {
public:
    using Base::process;
    void process(int a, float b);
};

As previous method don't silent the lint warning, an other way to solve that is to override each method process:

class derived: public Base {
public:
    void process(x) { Base::process(x); }
    void process(int a, float b);
};


来源:https://stackoverflow.com/questions/21462908/warning-overloaded-virtual-function-baseprocess-is-only-partially-overridde

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!