Форум: "Прочее";
Текущий архив: 2013.10.13;
Скачать: [xml.tar.bz2];
ВнизРеализация интерфейсов Найти похожие ветки
← →
Dimka Maslov © (2013-05-01 10:39) [0]Допустим у меня есть интерфейс IA, от которого унаследован интерфейс IB. Я объявляю класс
class TA(IA)
, в котором я реализую методы IA. Далее я объявляюclass TB(TA, IB)
, в котором я реализую только методы IB, ибо методы IA уже реализованы в базовом классе.
Теперь переходим на C++.
пишуclass CA : public IA
где реализую методы IA, потомclass CB : public CA, public IB
и вот тут сишный компилятор начинает ругаться, на абстрактные методы класса CB, заставляя заново реализовывать методы IА и всю иерархию наследования вплоть до IUnknown. Вопрос: зачем они заставляют это делать, если все методы уже реализованы, как виртуальные методы в базовом классе?
← →
clickmaker © (2013-05-01 13:12) [1]не ругается
class IA
{
public:
virtual void MethodA() = 0;
virtual void MethodA1() = 0;
};
class IB
{
public:
virtual void MethodB() = 0;
virtual void MethodB1() = 0;
};
class A: public IA
{
public:
virtual void MethodA() {}
virtual void MethodA1() {}
};
class B: public A, public IB
{
public:
virtual void MethodB() {}
virtual void MethodB1() {}
};
← →
Dimka Maslov © (2013-05-01 13:55) [2]Начнёт ругаться, когда попытаешься создать экземпляр класса B. Ну а кроме того надо написать class IB : public IA. Чтобы уж точно заругался.
← →
clickmaker © (2013-05-01 14:07) [3]ну логично. Если класс CB реализует IB, то он должен реализовать и его методы и методы его базового интерфейса. Нужно как-то пересмотреть логику. Отказаться от class IB : public IA, например
← →
Dimka Maslov © (2013-05-01 14:14) [4]Если я реализую интерфейс я физически не могу отказаться от __interface IA : public IUnknown. В Delphi при этом существует TInterfacedObject, использование которого избавляет от реализации QueryInterface, AddRef и Release.
← →
clickmaker © (2013-05-01 14:43) [5]как вариант
__interface IA
{
public:
virtual void MethodA();
virtual void MethodA1();
};
__interface IB : public IA
{
public:
virtual void MethodB();
virtual void MethodB1();
};
class CAB: public IB
{
public:
virtual void MethodA() {}
virtual void MethodA1() {}
virtual void MethodB() {}
virtual void MethodB1() {}
};
← →
Dimka Maslov © (2013-05-01 15:10) [6]Сваливать всё в один класс - нехорошо. Каша получится.
← →
clickmaker © (2013-05-01 16:48) [7]
class IA
{
public:
virtual void MethodA() = 0;
virtual void MethodA1() = 0;
};
class IB : virtual public IA
{
public:
virtual void MethodB() = 0;
virtual void MethodB1() = 0;
};
class CA: virtual public IA
{
public:
virtual void MethodA() {}
virtual void MethodA1() {}
};
class CB: public CA, public IB
{
public:
virtual void MethodB() {}
virtual void MethodB1() {}
};
← →
Dimka Maslov © (2013-05-01 19:31) [8]Не канает. При попытке создать экземпляр CB говорит, что класс абстрактный
← →
clickmaker © (2013-05-01 19:32) [9]у меня создается
← →
Dimka Maslov © (2013-05-01 19:56) [10]Вот так не канает:
[uuid(350332CE-12B9-43B5-8C4F-9A25BE9C5FA2)]
__interface IA : IUnknown
{
void __stdcall A();
};
class CUnknown : virtual public IUnknown
{
public:
CUnknown(): m_RefCount(0) {};
HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObj)
{
if ( riid == __uuidof(IUnknown) )
{
*ppvObj = static_cast<IUnknown*>(this);
AddRef();
return S_OK;
}
*ppvObj = 0;
return E_NOINTERFACE;
}
ULONG __stdcall AddRef()
{
InterlockedIncrement(&m_RefCount);
};
ULONG __stdcall Release()
{
if ( InterlockedDecrement(&m_RefCount) == 0 )
{
delete this;
return 0;
}
return m_RefCount;
}
private:
ULONG m_RefCount;
}
class CA : public CUnknown, public IA
{
public:
void A() {}
};
int main(int argc, char **argv)
{
CA ca;
}
← →
clickmaker © (2013-05-01 20:35) [11]class IA : virtual public IUnknown
← →
Dimka Maslov © (2013-05-01 20:40) [12]IA - объявляется как интерфейс, а не как класс, а у них не бывает виртуального базового класса
← →
clickmaker © (2013-05-01 20:44) [13]> объявляется как интерфейс, а не как класс
а какая разница? IUnknown - вообще структура
← →
Dimka Maslov © (2013-05-01 21:00) [14]видимо есть, раз не даёт написать __interface IA : virtual public IUnknown
← →
clickmaker © (2013-05-01 21:02) [15]> [14] Dimka Maslov © (01.05.13 21:00)
да нет, тебе какая разница? почему принципиально __interface?
← →
Сергей М. © (2013-05-01 21:02) [16]Дык правильно ж в народе бают: то что в Делфи делается просто, быстро, очевидно и интуитивно ожидаемо/понятно - тоже самое в сях если и делается, то обычно через причинное место)
← →
Dimka Maslov © (2013-05-01 21:18) [17]
> да нет, тебе какая разница? почему принципиально __interface?
Внутри одного модуля - действительно всё равно. Но я пишу планирую потом экспортировать интерфейсы куда-нибудь ещё, в том числе в модули, написанные на Delphi. Вот тут вроде как разница начинает ощущаться.
> Сергей М. © (01.05.13 21:02) [16]
Да, но ядро системы согласно техзаданию должно быть написано на C++
← →
clickmaker © (2013-05-01 21:34) [18]> [17] Dimka Maslov © (01.05.13 21:18)
IUnknown объявлен как структура. Вроде как нету проблем с его экспортом
#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE
MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
IUnknown
← →
clickmaker © (2013-05-01 21:57) [19]> [16] Сергей М. © (01.05.13 21:02)
да нет... просто с плюсами надо обращаться по принципу "не все то золото, что возможности языка предлагают"
← →
Dimka Maslov © (2013-05-01 23:57) [20]
> clickmaker © (01.05.13 21:34) [18]
А если я объявлю интерфейс-наследник как класс? Он будет правильно экспортироваться?
← →
clickmaker © (2013-05-02 00:31) [21]> [20] Dimka Maslov © (01.05.13 23:57)
оформи свою библиотеку как COM-сервер
← →
Dimka Maslov © (2013-05-02 00:39) [22]Она и так COM-cервер.
← →
clickmaker © (2013-05-02 13:16) [23]__interface - это вообще расширение MS для упрощения описания интерфейса. По сути - та же структура
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2013.10.13;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.002 c