简体   繁体   中英

C++ pure virtual functions implementation in derived class

I have a top API (based on abstract class) which is composed by a base API (that will be reused by different top APIs).

class api_base {
public:
    virtual int foo() = 0;
};

class api_top : public api_base {
public:
    virtual int bar() = 0;
}

Then, I want to provide a base implementation for base API:

class imp_base {
public:
    int foo() { return 1; }
}

And finally implement top API using base implementation for those functions defined in base API:

class imp_top : public api_top, public imp_base {
public:
    int bar() { return 1; }
}

When I instantiate an object of imp_top type, compiler say that foo() function is not implemented. But that is not true, since imp_top derives from imp_base , which do have foo() function implemented.

Any advice about this?

Thank you in advance.

Full test code:

    #include <stdio.h>

    class api_base { 
    public:
        virtual int foo() = 0;
    };

    class api_top : public api_base { 
    public:
        virtual int bar() = 0;
    };

    class imp_base { 
    public:
        int foo() { printf("foo from imp_base\n"); } 
    };

    class imp_top : public api_top, public imp_base { 
    public:
        int bar() { printf("bar from imp_top\n"); } 
    };

    int main()
    { 
       printf("Hello\n");                                                                                                                                                                                                                                                   
       imp_top a;

       a.bar();
       a.foo();

       return 1;
    }

Compiler result:

    test.cpp:26:12: error: cannot declare variable ‘a’ to be of abstract type ‘imp_top’                                                                                                                                                                                     
        imp_top a;
                ^
    test.cpp:18:7: note:   because the following virtual functions are pure within ‘imp_top’:
     class imp_top : public api_top, public imp_base {
           ^
    test.cpp:5:17: note:  virtual int api_base::foo()
         virtual int foo() = 0;
                     ^
    test.cpp:29:6: error: request for member ‘foo’ is ambiguous
        a.foo();
          ^
    test.cpp:15:9: note: candidates are: int imp_base::foo()
         int foo() { printf("foo from imp_base\n"); }
             ^
    test.cpp:5:17: note:                 virtual int api_base::foo()
         virtual int foo() = 0;

First Always use override keyword when redefining the functions in child classes.

Second read about virtual inheritance.

The following works :

class api_base {
public:
    virtual int foo() = 0;
};

class api_top : public virtual api_base {
public:
    virtual int bar() = 0;
};

class imp_base : public virtual api_base {
public:
    int foo() override { printf("foo from imp_base\n"); return 0; }
};

class imp_top : public api_top, public imp_base {
public:
    int bar() override { printf("bar from imp_top\n"); return 0; }
};


int main(){
    imp_top a;

    a.bar();
    a.foo();
return 1;
}

You should have used the override keyword, then you would had noticed that you did not implement the interface but defined an entirely new foo() method.

You will need to derive both imp_base and api_top from api_base by virtual inheritance.

Change:

class api_top : public api_base to class api_top : public virtual api_base

and:

class imp_base to class imp_base : public virtual api_base

Then it works.

To understand this, see: virtual inheritance . And yes (just saw Ext3h's post), use the override keyword.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM