Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > где находится реализация CWinApp::Run


Автор: pms 23.6.2006, 01:14
А скажите, пожалуйста, кто знает, почему CWinApp::Run объявлена как virtual. И где находится реализация этой функции? smile  

Автор: SergeCpp 23.6.2006, 08:51
Виртуальная она для того, чтобы Вы могли её при желании переопределить в производном классе.

APPCORE.CPP
Код
// Main running routine until application exits
int CWinApp::Run()
{
    if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
    {
        // Not launched /Embedding or /Automation, but has no main window!
        TRACE0("Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
        AfxPostQuitMessage(0);
    }
    return CWinThread::Run();
}

THRDCORE.CPP
Код
// main running routine until thread exits
int CWinThread::Run()
{
    ASSERT_VALID(this);

    // for tracking the idle time state
    BOOL bIdle = TRUE;
    LONG lIdleCount = 0;

    // acquire and dispatch messages until a WM_QUIT message is received.
    for (;;)
    {
        // phase1: check to see if we can do idle work
        while (bIdle &&
            !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
        {
            // call OnIdle while in bIdle state
            if (!OnIdle(lIdleCount++))
                bIdle = FALSE; // assume "no idle" state
        }

        // phase2: pump messages while available
        do
        {
            // pump message, but quit on WM_QUIT
            if (!PumpMessage())
                return ExitInstance();

            // reset "no idle" state after pumping "normal" message
            if (IsIdleMessage(&m_msgCur))
            {
                bIdle = TRUE;
                lIdleCount = 0;
            }

        } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
    }

    ASSERT(FALSE);  // not reachable
}

Пример переопределения
Код
int LifeApp::Run()
{
    for(;;)
    {
        BOOL msg  ( FALSE );
        BOOL idle ( TRUE  );
        long count( 0     );

        do
        {
            idle &=   OnIdle     (    count++ );
            msg   = ::PeekMessage( &m_msgCur, NULL, NULL, NULL, PM_REMOVE );
        }
        while( idle && ( !msg || m_msgCur.message == WM_KICKIDLE ) );

        do
        {
            if( !msg )
            {
                ::GetMessage( &m_msgCur, NULL, NULL, NULL );
            }

            if( m_msgCur.message == WM_QUIT )
            {
                return ExitInstance();
            }

            if( m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage( &m_msgCur ) )
            {
                ::TranslateMessage( &m_msgCur );
                ::DispatchMessage ( &m_msgCur );
            }

            if( IsIdleMessage( &m_msgCur ) )
            {
                idle  = TRUE;
                count = 0;
            }

            msg = ::PeekMessage( &m_msgCur, NULL, NULL, NULL, PM_REMOVE );
        }
        while( msg );
    }
}
  

Автор: pms 30.6.2006, 10:33
Благодарю за ответ. Но вот еще, что не совсем понятно. Почему нельзя добраться до реализации этой функции обычным путем, т.е. по цепочке предок->потомок. Вот что получается:
MyProgram.h
Код

...
class CMyProgramApp : public CWinApp
...


<Go To Declaration of CWinApp>

AFXWIN.H
Код

...
class CWinApp : public CWinThread
{
...
virtual int Run();
<Go To Definition of Run>
...
}
...
class CWinThread : public CCmdTarget
{
virtual int Run();
}


Т.е. получается что она изначально объявляется в CWinThread как virtual, наследуется в CWinApp снова без реализации, далее в CMyProgramApp, но и здесь ее реализации нет. Что не верно в моих рассуждениях? 

Автор: SergeCpp 30.6.2006, 10:40
Реализация представлена Вам в первом моём ответе...

Первое окно с кодом — это реализация CWinApp::Run()
Второе окно с кодом — это реализация CWinThread::Run()

http://www.research.att.com/~bs/glossary.html#Gvirtual-member-function
http://www.research.att.com/~bs/glossary.html#Gpure-virtual-function 

Автор: pms 30.6.2006, 11:42
Да я понял, что это реализация. Но я хочу узнать как компилятор "узнает", что это есть реализация этой функции? Прошу прощения за недостаточную внятность вопросов... 

Автор: SergeCpp 30.6.2006, 11:54
С указателем на объект связана таблица vtable, где находятся указатели на виртуальные функции.
Узнаёт не компилятор. Во время выполнения производится переход по этому указателю.
Это вкратце. 

Автор: pms 30.6.2006, 13:02
Спасибо. Кстати, а где вообще происходит вызов этой функции? Или может Вы скажете где подробнее можно об этом прочесть? 

Автор: SergeCpp 30.6.2006, 13:07
http://www.research.att.com/~bs/dne.html

user posted image

Вот http://anatolix.naumen.ru/Books/CPlusPlus?v=v3z есть несколько прекрасных книг

Ну, и это...
user posted image 

Автор: DeadSoul 1.7.2006, 09:50
Цитата(pms @  30.6.2006,  13:02 Найти цитируемый пост)
Кстати, а где вообще происходит вызов этой функции? Или может Вы скажете где подробнее можно об этом прочесть? 

Книга Круглински тебе поможет. Ссылки на нее уже давали 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)