[C++] 선행 선언에 대한 질문입니다.

lformula의 이미지

KLDP에는 초행인데 질문부터 올려서 참 죄송합니다만......

프레임이라는 클래스와 챠일드라는 클래스들이 서로를 참조해야 하기 때문에 프레임 클래스를 선행 선언하고 챠일드 클래스들을 작성한 뒤 프레임 클래스를 작성했습니다.

그런데 선행 선언을 한 뒤에 자꾸 오류가 발생해 버립니다.

#include "resource.h"
#include "wap.h"

using namespace wap;

class oFrame;

class oChildEdit : public oMDIChild {
public:
oEdit myEdit;
oMenu myMenu;
oMenu myMenuSub;

BeginMsgProc()
CreateMsg()
MDIActivateMsg()
SizeMsg()
SetFocusMsg()
DestroyMsg()
EndMsgProcOnMDIChild()

LRESULT OnCreate(CREATESTRUCT *pcs)
{
if(!myMenu.Load(MAKEINTRESOURCE(IDR_MENU3))) return -1;

myMenuSub = myMenu.GetSub(1);
if(!myMenuSub.Is()) return -1;

if(!myEdit.Create(0, WS_VISIBLE | ES_AUTOHSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | WS_HSCROLL | WS_VSCROLL, 0, 0, 0, 0, this, 100)) return -1;

return 0;
}

LRESULT OnSize(unsigned int nFlags, int nWidth, int nHeight)
{
MoveWindow(0, 0, nWidth, nHeight, true);

return 0;
}

LRESULT OnSetFocus(oHWND *poHWND)
{
myEdit.SetFocus();

return 0;
}

LRESULT OnDestroy(void)
{
delete this;

return 0;
}

LRESULT OnMDIActivate(oHWND *poHWND)
{
oMDIClient myMDIClient = GetParent();
oFrame *poFrame = myMDIClient.GetParentImplemented();

if(poHWND == this) myMDIClient.MDISetMenu(&myMenu, &myMenuSub);
else myMDIClient.MDISetMenu(&(poFrame->GetFrameMenu()), &(poFrame->GetFrameMenuSub())); // 이 부분에서 오류가 발생합니다.
// error C2027 정의되지 않은 형식 'oFrame'을(를) 사용했습니다. 라는 오류와 함께 밑에
// (6)(선행선언이 된 라인) : 'oFrame' 선언을 참조하십시오. 라는 문구가 뜹니다.

poFrame->DrawMenuBar(); // 이 라인에서도 같은 문제가 발생해 버립니다.

return 0;
}
};

class oChildDraw : public oMDIChild {
public:
oMenu myMenu;
oMenu myMenuSub;

oDC myDC;

int x;
int y;
bool bDrawNow;

BeginMsgProc()
CreateMsg()
MDIActivateMsg()
LButtonDownMsg()
LButtonUpMsg()
LButtonDblClkMsg()
MouseMoveMsg()
EndMsgProcOnMDIChild()

LRESULT OnCreate(CREATESTRUCT *pcs)
{
if(!myMenu.Load(MAKEINTRESOURCE(IDR_MENU2))) return -1;

myMenuSub = myMenu.GetSub(1);
if(!myMenuSub.Is()) return -1;

bDrawNow = false;

return 0;
}

LRESULT OnMDIActivate(oHWND *poHWND)
{
oMDIClient myMDIClient = GetParent();
oFrame *poFrame = myMDIClient.GetParentImplemented();

if(poHWND == this) myMDIClient.MDISetMenu(&myMenu, &myMenuSub);
else myMDIClient.MDISetMenu(&(poFrame->GetFrameMenu()), &(poFrame->GetFrameMenuSub())); // 이 라인에서도 같은 문제가 발생해 버립니다.

poFrame->DrawMenuBar(); // 이 라인에서도 같은 문제가 발생해 버립니다.

return 0;
}

LRESULT OnLButtonDown(unsigned int nFlags, int x, int y)
{
this->x = x;
this->y = y;
bDrawNow = true;

return 0;
}

LRESULT OnLButtonUp(unsigned int nFlags, int x, int y)
{
bDrawNow = false;

return 0;
}

LRESULT OnLButtonDblClk(unsigned int nFlags, int x, int y)
{
InvalidateRect(NULL, true);

return 0;
}

LRESULT OnMouseMove(unsigned int nFlags, int x, int y)
{
if(bDrawNow) {
myDC = GetDC();
myDC.MoveToEx(this->x, this->y, NULL);

this->x = x;
this->y = y;
myDC.LineTo(this->x, this->y);

ReleaseDC(&myDC);
}

return 0;
}
};

class oFrame : public oWnd {
public:
oMDIClient myMDIClient;

oMenu myMenu;
oMenu myMenuSub;

BeginMsgProc()
CreateMsg()
CommandMsg()
DestroyMsg()
EndMsgProcOnMDIClient(&myMDIClient);

LRESULT OnCreate(CREATESTRUCT *pcs)
{
if(!myMenu.Load(MAKEINTRESOURCE(IDR_MENU1))) return -1;

myMenuSub = myMenu.GetSub(0);
if(!myMenuSub.Is()) return -1;

if(!SetMenu(&myMenu)) return -1;

if(!myMDIClient.Create(0, WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN, this, 30000, &myMenuSub, 40000)) return -1;
myMDIClient.Show(SW_SHOW);

return 0;
}

LRESULT OnCommand(unsigned int nID, unsigned int nNtfMsg, oHWND *pohWnd)
{
BeginIDMap()
When(ID_FILE_NEWEDIT) myMDIClient.CreateMDIWindow(TEXT("myChild"), TEXT("Edit"), MDIS_ALLCHILDSTYLES); break;
When(ID_FILE_NEWDRAW) myMDIClient.CreateMDIWindowW(TEXT("myChild"), TEXT("Draw"), MDIS_ALLCHILDSTYLES); break;
When(ID_WIN_TILE) myMDIClient.MDITile(MDITILE_HORIZONTAL); break;
When(ID_WIN_CASCADE) myMDIClient.MDICascade(MDITILE_SKIPDISABLED); break;
When(ID_WIN_ARRANGE) myMDIClient.MDIIconArrange(); break;
EndIDMap()
}

LRESULT OnDestroy(void)
{
::PostQuitMessage(0);
return 0;
}

oMenu GetFrameMenu(void)
{
return myMenu;
}

oMenu GetFrameMenuSub(void)
{
return myMenuSub;
}
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
oFrame myFrame;
oWCX myWCX;
oMsg myMsg;

myWCX.SetBackground((HBRUSH)COLOR_APPWORKSPACE + 1);
myWCX.SetStyle(0);
myWCX.Register(TEXT("myFrame"));

myWCX.SetBackground((HBRUSH)::GetStockObject(WHITE_BRUSH));
myWCX.SetIcon(::LoadIcon(NULL, IDI_ASTERISK));
myWCX.Register(TEXT("myChildEdit"));

myWCX.SetStyle(CS_DBLCLKS);
myWCX.SetIcon(::LoadIcon(NULL, IDI_ERROR));
myWCX.Register(TEXT("myChildDraw"));

myFrame.Create(0, TEXT("myFrame"), TEXT("wapTest"), WS_OVERLAPPEDWINDOW);
myFrame.Show(nCmdShow);

return myMsg.Run();
}

분명히 선행선언을 해 주었는 것 같은데도 이러는 이유가 뭔지 궁금합니다. 혹시나 하여 인클루드 했던 헤더파일을 첨부합니다.

File attachments: 
첨부파일 크기
Plain text icon wap.txt28.09 KB
antaran의 이미지

LRESULT OnMDIActivate(oHWND *poHWND)
{
oMDIClient myMDIClient = GetParent();
oFrame *poFrame = myMDIClient.GetParentImplemented();

if(poHWND == this) myMDIClient.MDISetMenu(&myMenu, &myMenuSub);
else myMDIClient.MDISetMenu(&(poFrame->GetFrameMenu()), &(poFrame->GetFrameMenuSub())); // 이 부분에서 오류가 발생합니다.
// error C2027 정의되지 않은 형식 'oFrame'을(를) 사용했습니다. 라는 오류와 함께 밑에
// (6)(선행선언이 된 라인) : 'oFrame' 선언을 참조하십시오. 라는 문구가 뜹니다.

poFrame->DrawMenuBar(); // 이 라인에서도 같은 문제가 발생해 버립니다.

return 0;
}

컴파일러가 이 함수를 컴파일 할 때 알고 있는 것은 class oFrame ; , 그냥 oFrame이란 class가 있구나

라는 것 밖에 없습니다. 실제 oFrame은 한참 아래에 정의되어 있죠.

member function 정의를 class 내부에서 하지 마시고 아래처럼 바깥으로 꺼내 주시면 해결 될 겁니다.

// class 선언
class oChildEdit : public oMDIChild {
public:
oEdit myEdit;
oMenu myMenu;
oMenu myMenuSub;

BeginMsgProc()
CreateMsg()
MDIActivateMsg()
SizeMsg()
SetFocusMsg()
DestroyMsg()
EndMsgProcOnMDIChild()

} ;

class oFrame
{
// 생략
} ;

// 멤버함수 정의
LRESULT oChildEdit::OnMDIActivate(oHWND *poHWND)
{
// 생략
}

// ... 생략

그럼 이만...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.