2009-08-14 3 views
0

У меня проблема с отправкой декларации на работу (на самом деле я не уверен, что она должна работать так, как я предполагаю).Проблема с прямой декларацией

У меня есть файл CPP следующим образом:

int DialogModeless::Create(int dialogID, Presenter* pPresenter) 
{ 
    Ptrs* pPtrs = new Ptrs; 
    pPtrs->pPresenter = pPresenter; 
    pPtrs->pWnd = _derived; 
    HINSTANCE hInstance = ::GetModuleHandle(NULL); 
    _hWnd = ::CreateDialogParam(hInstance, MAKEINTRESOURCE(dialogID), NULL, &Presenter::StatDlgProc, 
     reinterpret_cast<LPARAM>(pPtrs)); 
    return 0; 
} 

Теперь путь у меня есть это то, что Presenter :: StatDlgProc должны быть объявлены только в этой точке, так как я только принимая его адрес. Это, кажется, не так, как я получаю следующее сообщение об ошибке из Visual Studio 2008:

ошибка C2027: использование неопределенного типа «Presenter»

я должен включить Presenter.h для кода для компиляции ,

Может кто-нибудь объяснить это мне?

Я попытался направить объявить, как это:

class Presenter; 
BOOL CALLBACK Presenter::StatDlgProc(HWND, UINT, WPARAM, LPARAM); 
+0

Итак, как вы переходите-декларируете 'StatDlgProc'? Пожалуйста, покажите код. –

ответ

0

Вам нужно объявить класс, а также функцию (например, в файле CPP), как это:

class Presenter; 

Это говорит компилятору, что Presenter - это класс, поэтому он знает, как справиться с ним.

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

+0

Хорошо, я надеюсь, что вы говорите, что лучше всего включить в это конкретное обстоятельство, а не в общем ... и, кстати, вы знаете Джейсона Уильямса? – Goz

+0

Yep and yep :-) –

5

без определения класса Presenter, компилятор не может принять адрес Presenter::StatDlgProc. В частности, он не знает, является ли он виртуальным или нет. Если он виртуальный, ему необходимо знать макет виртуальной таблицы класса, чтобы генерировать код, который будет искать вызов функции. (Если он статичен, компилятор теоретически может разрешить адрес во время связи.) Таким образом, без определения класса, компилятор не может решить, следует ли генерировать инструкции для простого вызова функции или для поиска виртуальной функции.

+0

Можно ли взять адрес функции неклассов в глобальной области с помощью только прямого отклонения? – 2009-08-15 08:32:40

+0

как: 'void func (int parm); funcPtr = &func; 'Да, это должно быть возможно - компоновщик может решить эту проблему. – AShelly

0

Если вы вперед объявить класс презентаторов либо:

class Presenter; 

, как Джейсон предложил или в создании декларации, как так:

int DialogModeless::Create(int dialogID, class Presenter* pPresenter); 

но не включая полное объявление не существует никакого способа доступ к любому члену, будь то статический, виртуальный или член.

Теперь вы можете легко структурировать файлы заголовков. Хотя modelessdialog.cpp зависит от presenter.h, но modelessdialog.h не так, нет трудного взаимодействия между файлами заголовка.

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