2012-12-02 2 views
2

VC C++ 2008에서 MFC 버전으로 Visual C++ 6.0에서 이식하는 응용 프로그램입니다. 수행의 많은 GET-AfxGetMainWnd() -and-DO-C-스타일 - 캐스트과 같이 그 위에 : 메인 윈도우가 더 이상 없다는 것을 나는 단순히 dynamic_cast<>로 전환, 위의 단계를하려고하면AfxGetMainWnd에서 C 스타일의 캐스트를 VC6/MFC6의 캐스트를 현대 MFC 버전 (VC++ 2008 이상)에서 변환하는 데 사용합니다.

CUserInterfaceDoc *m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd()) 
          ->GetActiveDocument(); 

, 내가 발견 내 프로그램에서 캐스팅 - 투 - CUserInterfaceDoc을 통해 액세스 할 수 있습니다. 아마도 MFC가 VC++ 6에서 캐스트를 남용했거나 컴파일러가 마술을했다고 생각합니다.

같이 갈 것 동적 캐스트를 사용하는 위의 다시 쓰기, 그리고 내가 그것을 원하는대로 내가 여기에 쓴 조건 어설() 여행 nil의 포인터로 끝나는 :

CUserInterfaceDoc *m_pDoc; 
CWnd * mainWnd = AfxGetMainWnd(); 
assert(mainWnd); 
CFrameWnd *frmWnd = dynamic_cast<CFrameWnd *> (mainWnd); 
assert(frmWnd); 
m_pDoc = dynamic_cast<CUserInterfaceDoc *> (frmWnd); 
assert(m_pDoc); 

I 전에 이것을 해본 모든 사람들이 "그래, 물론 캐스팅 행동을 바꿨다."라고 말할 수있을 것이라고 가정하지만 나는 그것에 대한 문서를 찾을 수 없다.

내가 AfxMainWnd()은 "더 많거나 적은 세계"에서 내려 도보로는 이전에 발견 된 것들에
링크를 저장할 멤버 변수 (필드)가 내 C++ 클래스를 변경하고있어 가능한 경우.

내가 무엇이 바뀌 었는지 알면 도움이 될 것입니다. 그래서 위의 상황을 이해할 수 있습니다.

CUserInterfaceDoc은 내 응용 프로그램의 MFC C++ Document 클래스이며 런타임시 C 스타일의 맨 위로 캐스팅 된 "findable"이었던 COleServerDoc입니다.

위의 캐스트는 여전히 최신 C++에서 컴파일되지만 이전 VC++ 6 컴파일러가 ISO C++ 표준에 위배되는 C 스타일의 캐스트로 일종의 내부 '마법'을 만들었 기 때문에 깨졌습니다. (그건 내 생각에 순전히 추측입니다.) 현재 주를 CFrameWnd에 대한 참조를 갖지 않고 사용했던 다른 클래스에서 CurrentDocument (를 CFrameWnd :: CurrentDocument)에서 얻을 수있는 일반적인 방법을 무엇

  1. :

    내 질문은 두 부분이다 해킹 나는이 질문의 상단에?

  2. 위의 캐스트 식의 동작을 변경하는 비 ISO 호환 VC++ 6 및 다소 호환되지 않는 ISO 호환 이후 C++ 버전간에 변경된 사항 또는 MFC 내부 아키텍처로 인해 손상이 발생했는지 여부 변화?

내 코드 변경 :

CUserInterfaceDoc * CMyBrowser::GetUserInterfaceDoc() 
{ 
    CUserInterfaceDoc *m_pDoc; 
    // formerly did this, which works in VC++6 and doesn't work anymore: 
    //m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd())->GetActiveDocument(); 
    assert(m_pMainFrm); 
    m_pDoc = dynamic_cast<CUserInterfaceDoc *> (m_pMainFrm->GetActiveDocument()); 
    assert(m_pDoc); 
} 

답변

1

:

CUserInterfaceDoc *m_pDoc; 
CWnd * mainWnd = AfxGetMainWnd(); 
assert(mainWnd); 
CFrameWnd *frmWnd = dynamic_cast<CFrameWnd *> (mainWnd); 
assert(frmWnd); 
m_pDoc = dynamic_cast<CUserInterfaceDoc *> (frmWnd); 
assert(m_pDoc); 

은 ... 당신은 단순히 C 스타일 캐스트에 있었던 GetActiveDocument() 호출을 놓쳤다.그래서 다음과 같이 작동합니다 :

CUserInterfaceDoc *m_pDoc; 
CWnd * mainWnd = AfxGetMainWnd(); 
assert(mainWnd); 
CFrameWnd *frmWnd = dynamic_cast<CFrameWnd *> (mainWnd); 
assert(frmWnd);  
m_pDoc = dynamic_cast<CUserInterfaceDoc *> (frmWnd->GetActiveDocument()); 
assert(m_pDoc); 

DYNAMIC_DOWNCAST은 김 oldschool하고 (기본적으로 설정되어 있습니다) RTTI를 사용하도록 설정하는 경우 실제로 더 이상 필요합니다. 다음을 참조하십시오 : MFC DYNAMIC_DOWNCAST vs. dynamic_cast

+0

2012 년부터의 답변은 꽤 오래된 것으로 보이고 다른 사람들은이 더 나은 조언을 찾을 수 있습니다. –

4

당신이 MFC를 사용하는 경우, 당신은뿐만 아니라 단지 총알을 물고와 MFC는 그 dynamic_cast는 기본적으로 동등의 캐스팅에 대한 매크로를 정의이다 DYNAMIC_DOWNCAST을 사용할 수 있습니다. 첫 번째 재 작성에

CFrameWnd* pFrm = DYNAMIC_DOWNCAST(CFrameWnd, AfxGetApp()->m_pMainWnd); 

m_pDoc = DYNAMIC_CAST(CUserInterfaceDoc, m_pMainFrm->GetActiveDocument()); 
+0

이 사용법은 여전히 ​​"수용 가능"하다고 간주되었거나 위의 사항이 MFC 오작동으로 간주됩니까? –

+0

MFC를 사용하는 경우 어떻게해야할까요? CObject에서 파생 된 클래스에 대해 MFC 프레임 워크에 고유 한 런타임 유형 정보를 활용합니다. –

+0

감사합니다. 그게 내가 정확히 필요한거야. –