Реализовать виртуальную функцию, унаследованную от A, используя конкретную функцию, унаследованную от B - PullRequest
0 голосов
/ 03 февраля 2019

Предположим, у меня есть класс интерфейса и класс частичной реализации.Кроме того, предположим, что я абсолютно не хочу, чтобы эта частичная реализация наследовала от интерфейса:

class interface {
    virtual void fnA() const = 0; 
    virtual void fnB() const = 0; 
};

class partialImplementation { //Do not want to inherit from interface!
    void fnA() const {cout << "fnA from partial implementation" << endl;}
    //fnB() not implemented
};

Идея состоит в том, что я планирую создать несколько новых классов, наследующих интерфейс, но я хочу реализоватьодинаковые fnA() в каждом.Итак, после наследования интерфейса, возможно, я мог бы также унаследовать частичную реализацию и надеяться, что fnA() будет реализован.Например,

class myClass : interface, partialImplementation {
    //would like fnA() to be implemented by partialImplementation
    void fnB() const {cout << "fnB from myClass" << endl;} 
};

Конечно, если вы попытаетесь создать экземпляр этого класса, вы получите эту ошибку:

main.cpp: In function 'int main()':
main.cpp:235:10: error: cannot declare variable 'm' to be of abstract type 'myClass'
main.cpp:201:7: note:   because the following virtual functions are pure within 'myClass':
main.cpp:193:15: note:  virtual void interface::fnA() const
Compilation failed.

После прочтения некоторых других сообщений stackoverflow (например, this один) кажется, что единственное доступное решение состоит в том, чтобы сделать это:

class myClass : interface, partialImplementation {
    public:
    void fnB() const {cout << "fnB from myClass" << endl;} 
    void fnA() const {
        partialImplementation::fnA();
    }
};

В связанном посте ОП не возражал против ввода трех дополнительных строк.Но вы можете себе представить, что я на самом деле хочу, чтобы partialImplementation реализовывал больше, чем одну функцию, и что я мог бы набирать один и тот же шаблон раз за разом, когда я хочу создать новый класс, наследующий этот интерфейс.

Кто-нибудь знает способ сделать это, не требуя partialImplementation наследовать от interface?

1 Ответ

0 голосов
/ 03 февраля 2019

Опция, которую вы не хотите

Непонятно, что вы собираетесь делать.Но одно можно сказать наверняка: в вашем решении fnA() из partialImplementation не имеет ничего общего с fnA() из interface, поскольку оба класса не связаны.Кроме того, в partialImplementation эта функция не является виртуальной.

Таким образом, чтобы получить partialImplementation fnA() как виртуальную функцию в классе, производном от интерфейса, явный вызов, который вы выставили, этоЕдинственный способ продолжить.

Если вы хотите избавиться от стандартного кода, вы должны сделать partialImplementation наследующим от interface.Это все еще будет абстрактный класс, создание которого невозможно, поскольку fnB() по-прежнему отсутствует.

class partialImplementation : public interface { ... };

class myClass : public partialImplementation {
public:
    void fnB() const {cout << "fnB from myClass" << endl;} 
};

Хотите объединить несколько частичных реализаций?

Непонятно, почему вы не хотите этого наследования.Если вы хотите объединить несколько различных частичных реализаций в смешанном стиле, но вы хотите избежать нескольких отдельных интерфейсных подобъектов, вы можете выбрать виртуальное наследование:

class partialImplementationA : public virtual interface { 
public: 
    void fnA() const {cout << "fnA from partial implementation A" << endl;}
};
class partialImplementationB : public virtual interface { 
public: 
    void fnB() const {cout << "fnB from partial implementation B" << endl;}
};

class myClass : public virtual interface, 
                public partialImplementationA, 
                public partialImplementationB {
public:
};

Online demo

Неудобство заключается в том, что наследство должно быть объявлено виртуальным на всех уровнях.Но это позволяет достичь того, что вы хотите сделать без стандартного кода.

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