Реализация чисто виртуальных функций C ++ в производном классе - PullRequest
0 голосов
/ 04 мая 2018

У меня есть top API (на основе абстрактного класса), который составлен из base API (который будет повторно использоваться различными top API).

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

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

Затем я хочу предоставить базовую реализацию для базового API:

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

И, наконец, реализовать top API, использующий базовую реализацию для тех функций, которые определены в базовом API:

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

Когда я создаю экземпляр объекта типа imp_top, компилятор говорит, что функция foo() не реализована. Но это не так, поскольку imp_top происходит от imp_base, в котором реализована функция foo().

Любой совет по этому поводу?

Заранее спасибо.

Полный код теста:

    #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;
    }

Результат компиляции:

    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;

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Изменение:

class api_top : public api_base до class api_top : public virtual api_base

и

class imp_base до class imp_base : public virtual api_base

Тогда это работает.

Чтобы понять это, см .: Виртуальное наследование . И да (только что увидел сообщение Ext3h), используйте ключевое слово override.

0 голосов
/ 04 мая 2018

Сначала всегда используйте ключевое слово override при переопределении функций в дочерних классах.

Второе чтение о виртуальном наследовании.

Следующие работы:

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;
}
0 голосов
/ 04 мая 2018

Вы должны были использовать ключевое слово override, тогда вы бы заметили, что не реализовали интерфейс, а определили совершенно новый метод foo().

Вам потребуется вывести как imp_base, так и api_top из api_base путем виртуального наследования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...