前向声明问题

时间:2009-08-14 20:27:10

标签: c++ windows winapi

我在使用声明工作时遇到了问题(实际上我不确定它是否应该像我想的那样工作)。

我有一个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);

3 个答案:

答案 0 :(得分:5)

没有Presenter的类定义,编译器不会如何获取Presenter::StatDlgProc的地址。具体来说,它不知道它是否是虚拟的。如果它是虚拟的,它需要知道类的vtable的布局,以便生成将查找函数调用的代码。 (如果它是静态的,编译器理论上可以在链接时解析地址。)因此,如果没有类定义,编译器就无法决定是为简单函数调用还是为虚函数查找发出指令。

答案 1 :(得分:0)

您需要声明类和函数(例如在您的cpp文件中),如下所示:

class Presenter;

这告诉编译器Presenter是一个类,所以它大致知道如何处理它。

但除非你有充分的理由(比如两个标题之间的循环依赖),否则#include正确的标题会更好。

答案 2 :(得分:0)

如果您通过以下方式转发声明演示者类:

class Presenter;

正如Jason建议的那样或在创建声明中如此:

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

但不包括完整声明,无论是静态,虚拟还是成员,都无法访问任何成员。

现在您可以轻松构建头文件。虽然modelessdialog.cpp依赖于presenter.h,但modelessdialog.h并不是这样,所以头文件之间没有任何困难的交互。