2015-01-22 2 views
2

... когда класс acatally предоставляет реализации для всех абстрактных методов, но не является «формальным» внедрением интерфейса?Как я могу реализовать класс для реализации интерфейса .... (C++)

Допустим, у меня есть следующие:

class AInterface { 
    public: 
     virtual void mem_func()=0; 
     virtual ~AInterface(){} 
}; 

void AFunction(AInterface* i){}; 

class BClass { 
    public: 
     void mem_func(){} 
     virtual ~BClass(){} 
}; 

и я не могу изменить все это, но я хочу использовать объект класса BClass вызвать прекращение функции.

На самом деле, я хотел бы написать что-то вроде

class MyABClass : public BClass,public AInterface {}; 

, но это не помогает (класс просто наследует оба метода и абстрактно). Я предполагаю, что один из способов сделать это писать что-то вроде

class MyABClass : public AInterface { 
    public: 
     void mem_func(){a.mem_func();} 
    private: 
     BClass a; 
} 

Это прекрасно работает, но мне интересно, если это возможно, чтобы сохранить некоторые письма или, если есть лучший способ справиться с этой ситуацией.

+0

Что вы пытаетесь достичь или это просто общее исследование ООП на C++? Похоже, вы пытаетесь реализовать Mixins, но я не совсем уверен. – BlamKiwi

+0

Почему бы не просто «класс MyClass: public AClass {}'? –

+0

Я не думаю, что вы можете сделать это, как хотите. Предположим, что AInterface :: A() не является чисто виртуальным, компилятор не может знать, какой из них вызывать, когда вы вызываете MyClass :: A(). Если AInterface :: A() является чистой вирутальной функцией, компилятор должен сначала найти A(). – imlyc

ответ

2

Я хотел бы использовать подход, весьма похожий на ваш последний фрагмент кода

class MyABClass : public AInterface { 
    public: 
     void MyABClass(BClass &_a) 
      : a(_a) 
     {} 
     void mem_func(){a.mem_func();} 
    private: 
     BClass &a; 
} 

Это шаблон дизайна и называется Adapter (с делегацией). Возможно, вы также захотите прочитать о шаблоне Proxy.

Обновление (с учетом комментария Kenny): передаете ли вы BClass в качестве справки или копии являются спорными. Это зависит от того, что вы хотите. Если вам нужна обертка для удобного изменения исходного экземпляра BClass, то в качестве параметра конструктора используйте BClass &. С другой стороны, если копии достаточно, используйте только BClass без амперсанда &. Ну, если имеется конструктор копирования. Наконец, вы должны обратить внимание при использовании ссылки, что вы можете создавать побочные эффекты (которые, опять же, могут быть желательными или нет).

+0

Да, использование стандартного объекта AClass делает мой фрагмент довольно бесполезным в некоторых случаях. И спасибо за указание, что это шаблон дизайна. Я всегда чувствую себя лучше с использованием хорошо зарекомендовавшего себя шаблона вместо своих собственных решений «как-то-я-он-работа»;) – user463035818

+0

Бонусные баллы за именование шаблона дизайна, но не используют ссылку. Как показывает ваша ссылка, прокси должен владеть частным экземпляром или расширять класс, чтобы он был экземпляром (что делает его другим эквивалентным ответом, множественным наследованием). –

0

Ваша первая попытка была почти сразу

class MyClass : public AClass,public AInterface {}; 

Проблема заключается в том, что MyClass не знает, что AClass :: A() удовлетворяет требованиям, создаваемую :: A-интерфейса() = 0. Дайте ему немного помочь, как так

class MyClass : public AClass, public AInterface { 
    void A() {AClass::A();} 
}; 
+1

@ tobi303 - ваш код с множественным наследованием был почти прав. Это исправляет его в одной незначительной детали, которой он не хватает. –

+0

после прочтения ваших сообщений и предыдущих изменений, я знаю, что вы имеете в виду, но я думаю, что неясно, какой код вы ссылаетесь, если кто-то читает мой вопрос и ваш ответ. – user463035818

Смежные вопросы