2

В моем классе дизайн я столкнулся следующая проблема:Абстрактный базовый класс головоломка

class MyData 
{ 
    int foo; 
}; 

class AbstraktA 
{ 
public: 
    virtual void A() = 0; 
}; 

class AbstraktB : public AbstraktA 
{ 
public: 
    virtual void B() = 0; 
}; 

template<class T> 
class ImplA : public AbstraktA 
{ 
public: 
    void A(){ cout << "ImplA A()"; }  
}; 

class ImplB : public ImplA<MyData>, public AbstraktB 
{ 
public: 
    void B(){ cout << "ImplB B()"; } 
}; 

void TestAbstrakt() 
{ 
    AbstraktB *b = (AbstraktB *) new ImplB; 
    b->A(); 
    b->B(); 
}; 

Проблема с выше кода является то, что компилятор будет жаловаться, что AbstraktA :: A() не определено.

Интерфейс A разделяется несколькими объектами. Но реализация A зависит от аргумента шаблона. Интерфейс B является видимым внешним миром и должен быть абстрактом.

Поэтому я хотел бы, что это позволило бы мне определить объект C, как это: Определение интерфейса C унаследованный от АБСТРАКТ А. Определить реализацию C с использованием другого типа данных для шаблона А.

Надеюсь, я поняла. Есть ли способ сделать это, или мне нужно переосмыслить мой дизайн?

+0

Я могу быть глупым, но почему «абстрактные» слова «абстракт». Это намеренно? –

+1

Хе-хе, нет причин вообще. Только результат моего родного языка :) –

+0

Возможный дубликат: http://stackoverflow.com/questions/254673/multiple-inheritance-from-two-derived-classes – Talvalin

ответ

9

У вас есть два пути наследования от AbstracktA, вы реализуете AbstraktA :: A() только в одном из них, поэтому компилятор жалуется.

Возможно, вы захотите наследовать фактически от AbstraktA в обоих случаях, чтобы существовал только один базовый объект AbstraktA (добавьте virtual до AbstraktA).

+0

Thank вы!! Это все. Какое легкое решение :) Я помню, что раньше я читал о виртуальном наследовании, но, поскольку я никогда не использовал его на практике, я полностью забыл об этом. Я боялся, что мне пришлось переосмыслить мой дизайн, потому что я не мог найти альтернативное решение, которое бы решило это. Еще раз спасибо. –

+0

Это работает, но приводит к предупреждению компилятора: «предупреждение C4250:„ImplB“:„наследуется ImplA :: ImplA :: А“с помощью доминирования» Является ли это что-то быть обеспокоены? – Talvalin

+0

@lalithv, это что-то беспокоит, если это не то, что вы хотите. В этом случае это то, что нужно. (Я думаю, что это предупреждение относится к категории «не очень распространено, имеет ложное положительное значение, чем истинное, его трудно избежать, реорганизовывая код в ложноположительном случае») – AProgrammer

0

Я забыл добавить виртуальных деструкторов в базовые классы. Это приводит к ошибкам malloc во время выполнения, которые, как я полагаю.

AbstraktB *b = new ImplB; 
b->A(); 
b->B(); 
delete b; 

В режиме отладки, в ВЕИТ, GCC дает мне: таНоса: *** ошибке для объекта 0x60e2c4: указатель освобождения не было выделен

Я решил эту проблему путем изменения базовых классов в :

class AbstraktA 
{ 
public: 
    virtual ~AbstraktA(){}; 
    virtual void A() = 0; 
}; 

class AbstraktB : virtual public AbstraktA 
{ 
public: 
    virtual ~AbstraktB(){}; 
    virtual void B() = 0; 
}; 

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

  • Нет связанных вопросов^_^