Как реализовать наследование от ветви интерфейсов и базовой реализации корневого интерфейса? Предположим что есть некий набор публичных интерфейсов (экспортируемых библиотекой):class IA { public: virtual void f1() = 0; }; class IB : public IA { public: virtual void f2() = 0; }; А также есть базовая реализация интерфейса IA:class A : public IA { public: void f1() { std::cout << "f1" << std::endl; } }; Необходимо реализовать интерфейс IB так, чтобы он предоставлял реализацию интерфейса IA классом A:// Этот код не компилируется class B : public IB, public A { public: void f2() { std::cout << "f2" << std::endl; } }; int main(int argc, char* argv[]) { B b; b.f1(); b.f2(); return 0; }Код на Coliru Можно ли это сделать, и как? Решение "в лоб" не подошло, с порядком и видимостью (public/protected/private) наследования игрался... ничего не помогло.
Для реализации наследования от ветви интерфейсов и базовой реализации корневого интерфейса можно воспользоваться множественным наследованием и виртуальным наследованием.
В данном случае, класс B должен наследоваться от IB и виртуально от A, чтобы избежать проблемы с дублированием базового класса при множественном наследовании. Также нужно переопределить метод f1 в классе B, чтобы вызывалась реализация из класса A.
Пример кода:
#include <iostream> class IA { public: virtual void f1() = 0; }; class IB : public virtual IA { public: virtual void f2() = 0; }; class A : public virtual IA { public: void f1() { std::cout << "f1" << std::endl; } }; class B : public IB, public A { public: void f2() { std::cout << "f2" << std::endl; } void f1() { A::f1(); } }; int main() { B b; b.f1(); b.f2(); return 0; }
Теперь класс B реализует интерфейс IB и является наследником класса A. Метод f1 вызывает реализацию из класса A, а метод f2 реализуется в классе B. В этом случае код компилируется и работает корректно.
Для реализации наследования от ветви интерфейсов и базовой реализации корневого интерфейса можно воспользоваться множественным наследованием и виртуальным наследованием.
В данном случае, класс B должен наследоваться от IB и виртуально от A, чтобы избежать проблемы с дублированием базового класса при множественном наследовании. Также нужно переопределить метод f1 в классе B, чтобы вызывалась реализация из класса A.
Пример кода:
#include <iostream>class IA {
public:
virtual void f1() = 0;
};
class IB : public virtual IA {
public:
virtual void f2() = 0;
};
class A : public virtual IA {
public:
void f1() {
std::cout << "f1" << std::endl;
}
};
class B : public IB, public A {
public:
void f2() {
std::cout << "f2" << std::endl;
}
void f1() {
A::f1();
}
};
int main() {
B b;
b.f1();
b.f2();
return 0;
}
Теперь класс B реализует интерфейс IB и является наследником класса A. Метод f1 вызывает реализацию из класса A, а метод f2 реализуется в классе B. В этом случае код компилируется и работает корректно.