C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Абстрактность неабстрактоного класса
juice
Отправлено: 04.07.2005, 10:12


Дежурный стрелочник

Группа: Участник
Сообщений: 33



EventInterface = new TMyOutlookEventsImpl; при выполнении такой строчки компилятор дает ошибку :

[C++ Error] Unit1.cpp(30): E2352 Cannot create instance of abstract class 'TMyOutlookEventsImpl'

Однако, класс TMyOutlookEventsImpl за исключением одной функции полностью создан мастером File/New/ActiveX/Automation Object, вот привожу его код:

Заголовочный файл класса:
CODE

// MYOUTLOOKEVENTSIMPL.H : Declaration of the TMyOutlookEventsImpl

#ifndef MyOutlookEventsImplH
#define MyOutlookEventsImplH

#define ATL_APARTMENT_THREADED

#include "MyOutlookEvents_TLB.h"


/////////////////////////////////////////////////////////////////////////////
// TMyOutlookEventsImpl     Implements IMyOutlookEvents, default interface of MyOutlookEvents
// ThreadingModel : Apartment
// Dual Interface : TRUE
// Event Support  : FALSE
// Default ProgID : Project1.MyOutlookEvents
// Description    :
/////////////////////////////////////////////////////////////////////////////
class ATL_NO_VTABLE TMyOutlookEventsImpl :
 public CComObjectRootEx<CComSingleThreadModel>,
 public CComCoClass<TMyOutlookEventsImpl, &CLSID_MyOutlookEvents_>,
 public IDispatchImpl<IMyOutlookEvents, &IID_IMyOutlookEvents, &LIBID_MyOutlookEvents>
{
public:
 TMyOutlookEventsImpl()
 {
 }

 // Data used when registering Object
 //
 DECLARE_THREADING_MODEL(otApartment);
 DECLARE_PROGID("MyOutlookEvents.MyOutlookEvents");
 DECLARE_DESCRIPTION("");

 // Function invoked to (un)register object
 //
 static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
 {
   TTypedComServerRegistrarT<TMyOutlookEventsImpl>
   regObj(GetObjectCLSID(), GetProgID(), GetDescription());
   return regObj.UpdateRegistry(bRegister);
 }

BEGIN_COM_MAP(TMyOutlookEventsImpl)
 COM_INTERFACE_ENTRY(IMyOutlookEvents)
 COM_INTERFACE_ENTRY2(IDispatch, IMyOutlookEvents)
END_COM_MAP()

// IMyOutlookEvents
public:
 virtual void __fastcall AfterConstruction();
 void STDMETHODCALLTYPE OnError(long Code, BSTR Description);
 void STDMETHODCALLTYPE Progress(Myoutlookevents_tlb::OlSyncState State, BSTR Description, long Value, long Max);
 void STDMETHODCALLTYPE SyncEnd();
 void STDMETHODCALLTYPE SyncStart();
};

extern TMyOutlookEventsImpl* EventInterface;

#endif //MyOutlookEventsImplH





CPP-файл описания класса:
CODE

// MYOUTLOOKEVENTSIMPL : Implementation of TMyOutlookEventsImpl (CoClass: MyOutlookEvents, Interface: IMyOutlookEvents)

#include <vcl.h>
#pragma hdrstop

#include "MYOUTLOOKEVENTSIMPL.H"

/////////////////////////////////////////////////////////////////////////////
// TMyOutlookEventsImpl

virtual void __fastcall AfterConstruction()
{
 TObject::AfterConstruction;
 EventInterface = this;
}

void STDMETHODCALLTYPE TMyOutlookEventsImpl::OnError(long Code,
 BSTR Description)
{

}

void STDMETHODCALLTYPE TMyOutlookEventsImpl::Progress(OlSyncState State,
 BSTR Description, long Value, long Max)
{
 //OlSyncStatePtr StatePtr(State, true);

}

void STDMETHODCALLTYPE TMyOutlookEventsImpl::SyncEnd()
{
}

void STDMETHODCALLTYPE TMyOutlookEventsImpl::SyncStart()
{
}

В чем же заключается абстрактоность этого класса, вроде как все определено должным образом ???

Отредактировано Георгий — 04/07/2005, 23:52
juice
Отправлено: 04.07.2005, 10:56


Дежурный стрелочник

Группа: Участник
Сообщений: 33



Только что заметил еще одно сообщение компилятора :
[C++ Error] Unit1.cpp(113): E2353 Class 'TMyOutlookEventsImpl' is abstract because of '__stdcall TMyOutlookEventsImpl::AddRef() = 0'

Насколько я понимаю , мне самостоятельно надо определить функцию-член AddRef ? Странно конечно, ведь она должна быть определена в билдеровских библиотеках ...
Я попытался обьявить ее так :
CODE
void __stdcall TMyOutlookEventsImpl::AddRef()
{
 //AddRef();
}
Проблема осталась.
И еще. Получается, что эта функция обьявляется в макросе
CODE

BEGIN_COM_MAP(TMyOutlookEventsImpl)
 COM_INTERFACE_ENTRY(IMyOutlookEvents)
 COM_INTERFACE_ENTRY2(IDispatch, IMyOutlookEvents)
END_COM_MAP()
Но как посмотреть его содержимое, в Delphi для перехода достаточно Ctrl+Left click, а тут я уже половину модулей вручную перелапатил но никак не могу найти где этот макрос обьявляется! Как поступаете в таких случаях вы ?

Отредактировано Георгий — 05/07/2005, 11:08
juice
Отправлено: 04.07.2005, 12:08


Дежурный стрелочник

Группа: Участник
Сообщений: 33



Нашел описание этого макроса:
CODE
#define END_COM_MAP() {NULL, 0, 0}}; return &_entries[1];} \
virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; \
virtual ULONG STDMETHODCALLTYPE Release( void) = 0; \
STDMETHOD(QueryInterface)(REFIID, void**) = 0;
Определил функции так:
CODE
virtual ULONG STDMETHODCALLTYPE TMyOutlookEvents::AddRef(void)
{
 //AddRef();
}

virtual ULONG STDMETHODCALLTYPE TMyOutlookEvents::Release(void)
{
 //AddRef();
}
Все осталось по-прежнему sad.gif

Отредактировано Георгий — 05/07/2005, 11:07
olegenty
Отправлено: 04.07.2005, 13:51


Ветеран

Группа: Модератор
Сообщений: 2412



это всё глюки Import Type Library. как ни нудно, но лучше напиши обёртку сам. (хотя, это зависит от того, чего и сколько ты собираешься использовать)
vvoid
Отправлено: 04.07.2005, 15:51


Машинист паровоза

Группа: Участник
Сообщений: 171



Привет!
Ты наследуешься от 3-х класов, их я не смотрел, но как совет: проверь переопределил ли ты ВСЕ чисто виртуальные функции базовых классов.
olegenty
Отправлено: 05.07.2005, 07:55


Ветеран

Группа: Модератор
Сообщений: 2412



ну-ну. можно предположить, что это тривиально? smile.gif
ребят, а вы точно уверены, что вам не слабо переопределить метод COM-интерфейса?
vvoid
Отправлено: 05.07.2005, 15:16


Машинист паровоза

Группа: Участник
Сообщений: 171



QUOTE
ребят, а вы точно уверены, что вам не слабо переопределить метод COM-интерфейса

Ну уж извините, если в классе объявили чисто виртуальную функцию, сделав его тем самым абстрактным, значит само собой разумеется, что кто-то должен написать код для этих функций. И если наследоваться от этих классов, то по другому нельзя. А по поводу реализации, то в книгах, в MSDN и т.д., я думаю, можно найти как это сделать, ведь изобретать что-то своё не надо, а реализация — дело техники.
Не думаю, что это сложнее чем писать драйвера wink.gif
Asher
Отправлено: 05.07.2005, 16:26


Мастер участка

Группа: Модератор
Сообщений: 550



juice писал:
QUOTE
Нашел описание этого макроса:
...
Определил функции так:
CODE
virtual ULONG STDMETHODCALLTYPE TMyOutlookEvents::AddRef(void)
{
//AddRef();
}



может все-же не TMyOutlookEvents а TMyOutlookEventsImpl ?
CODE

virtual ULONG __stdcall TMyOutlookEventsImpl::AddRef(){};

Вернуться в Вопросы программирования в C++Builder