2016-06-13 5 views
2

Возможно ли сделать следующее:
В моем базовом классе есть 3 чистых виртуальных функций. Мой производный класс реализует 2 из этих виртуальных функций и наследует от другого класса, который реализует последнюю третью виртуальную функцию.Разрешить другому базовому классу реализовать виртуальную функцию

Мой текущий код не будет компилироваться, поэтому я думаю, что это недействительно? Хотя было бы здорово, если бы я мог каким-то образом использовать этот подход. Ниже представлено мое практическое применение/использование этого подхода.

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

class ListBox 
{ 
public: 
    virtual void onScroll() = 0; 
    virtual void foo() = 0; 
    virtual void bar() = 0; 
}; 

class DragScrollHandler 
{ 
public: 
    void onScroll() 
    { 
     ... 
    } 
}; 

class HorzListBox: public ListBox, public DragScrollHandler // could also do public HoverScrollHandler, etc. 
{ 
public: 
    void foo() override 
    { 
     printf("foo\n"); 
    } 

    void bar() override 
    { 
     printf("foo\n"); 
    } 

    HorzListBox() 
     : ListBox(), DragScrollHandler() 
    { 

    } 
}; 

ответ

3

ListBox и DragScrollHandler являются априорными разными понятиями, так что нет никакого вида связи через множественное наследование. Я имею в виду, что не является автоматической установкой связи между виртуальным onScroll, унаследованным каким-то образом, и реализацией onScroll на другой не связанной (другой) ветке.

Вы можете определить его на HorzListBox вызвать унаследованную реализацию:

void onScroll() override { 
    DragScrollHandler::onScroll(); 
} 

Это будет выполнять контракт: реализовать абстракцию и использовать унаследованную реализацию.

Но может быть лучшим способом (в вашем случае), чтобы отделить понятия и иметь Scrollable:

class Scrollable { 
public: 
    virtual void onScroll()=0; 
}; 

class ListBox: virtual public Scrollable { 
public: 
    virtual void foo()=0; 
}; 

class DragScrollHandler: virtual public Scrollable { 
public: 
    void onScroll() override {...} 
}; 

class HorzListBox: public ListBox, public DragScrollHandler { 
public: 
    void foo() override {...} 
}; 
1

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

Внесите реализацию производного класса в другую реализацию базового класса.

class HorzListBox: public ListBox, public DragScrollHandler 
{ 
public: 
    void foo() override 
    { 
     printf("foo\n"); 
    } 

    void bar() override 
    { 
     printf("foo\n"); 
    } 

    void onScroll() override 
    { 
     DragScrollHandler::onScroll(); 
    } 

    HorzListBox() 
     : ListBox(), DragScrollHandler() 
    { 

    } 
}; 
-1

Мой текущий код не будет компилироваться, так что я имею в виду, что это не действует?

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

Так что в вашем случае класс HorzListBox также является абстрактным классом, так как он не отменяет все PVF класса ListBox.

Пожалуйста, переосмыслите эти строки и соответствующим образом измените свой код.

1

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

Ради любопытства, вы можете использовать подход, основанный на Mixin как следующий:

struct ListBox { 
    virtual ~ListBox() { } 
    virtual void onScroll() = 0; 
    virtual void foo() = 0; 
    virtual void bar() = 0; 
}; 

template<typename T> 
struct DragScrollHandler: T { 
    void onScroll() override { } 
}; 

template<typename T> 
struct HorzListBox: T { 
    void foo() override { } 
    void bar() override { } 
}; 

int main() { 
    ListBox *lb = new HorzListBox<DragScrollHandler<ListBox>>{}; 
} 
Смежные вопросы