Реализация интерфейсов в C ++ с унаследованными конкретными классами - PullRequest
9 голосов
/ 23 февраля 2012

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

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

Это то, что у меня есть.Я получаю сообщение об ошибке: «объект абстрактного класса« TObjectB »не разрешен».Мне кажется, я знаю почему, потому что я не реализовал MethodA () в TObjectB.Но я действительно хочу иметь реализацию, предоставляемую базовым классом (TObjectA), и при этом иметь интерфейсные иерархии (IInterfaceB наследует от IInterfaceA).Я также не хочу повторять все унаследованные методы интерфейса в моих производных конкретных классах.Как я могу это сделать?

class IInterfaceA 
{ 
public:
    virtual void MethodA() = 0; 
}; 

class IInterfaceB : IInterfaceA
{ 
public:
    virtual void MethodB() = 0; 
}; 

class TObjectA : public IInterfaceA 
{ 
public:
    void MethodA() { cout << "Method A"; }  
}; 

class TObjectB : public TObjectA, public IInterfaceB 
{ 
public:
    void MethodB() { cout << "Method B"; } 
}; 

void TestInterfaces()
{
    IInterfaceB* b = new TObjectB(); // error: object of abstract class type "TObjectB" is not allowed
    b->MethodB();
    delete b;
}

Ответы [ 2 ]

11 голосов
/ 23 февраля 2012

В вашей иерархии классов TObjectB на самом деле имеет два подобъекта базового класса IInterfaceA: один наследуется через IInterfaceB и один наследуется через TObjectA.MethodA() от каждого из них должен быть реализован.

Вам необходимо наследовать от классов интерфейса, используя публичное виртуальное наследование, которое гарантирует, что существует только один подобъект базового класса каждоготип класса интерфейса:

class IInterfaceA 
{ 
public:
    virtual void MethodA() = 0; 
}; 

class IInterfaceB : public virtual IInterfaceA
{ 
public:
    virtual void MethodB() = 0; 
}; 

class TObjectA : public virtual IInterfaceA 
{ 
public:
    void MethodA() { cout << "Method A"; }  
}; 

class TObjectB : public TObjectA, public virtual IInterfaceB 
{ 
public:
    void MethodB() { cout << "Method B"; } 
}; 

void TestInterfaces()
{
    TObjectB b_object;
    IInterfaceB& b = b_object;
    b.MethodB();
}

Желательны ли такие сложные иерархии классов - это совсем другой вопрос.

1 голос
/ 23 февраля 2012

Ваша проблема вызвана наследством страшных алмазов. Вы реализовали TObjectA::IInterfaceA::MethodA, но не IInterfaceB::IInterfaceA::MethodA.

Я бы рекомендовал сделать IIterfaceA и IIterfaceB полностью независимыми. Если это невозможно, вы можете посмотреть на виртуальное наследование.

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