青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

franksunny的個人技術空間
獲得人生中的成功需要的專注與堅持不懈多過天才與機會。 ——C.W. Wendte

symbian官方推薦使用活動服務對象(CActive)來代替多線程的使用,我想這個道理是很明了的,在手機這樣的小內存設備里,運行多線程的程序是非常耗資源的,為了節(jié)約資源,symbian提供了一個活動服務對象的框架,允許把程序里并發(fā)執(zhí)行對象(其實不是并發(fā),不過宏觀上看來是)放在一個線程里面執(zhí)行,這些并發(fā)工作的對象就通過活動規(guī)劃器(ActiveScheduler)來進行管理.

關于這兩個東西的介紹,網上有一大堆的文檔,我就不在這里廢話了,如何使用呢?這里我先舉一個簡單的計數(shù)器的例子.我選擇寫一個exe的程序,也就是說程序是以E32Main為入口的.

GLDEF_C TInt E32Main()

{

    CTrapCleanup* cleanup=CTrapCleanup::New();

    TRAPD(error,callInstanceL());

    if (error != KErrNone)

    {

        printf("get error %d\r\n", error);

    }

    delete cleanup;

    return 0;

}

以上的內容是每一個exe文件都應該做的,CTrapCleanup* cleanup=CTrapCleanup::New()建立一個清除堆棧,以便程序在異常退出的時候把清除堆棧里面的資源都釋放掉.當然你也可以加上堆檢測宏(__UHEAP_MARK,__UHEAP_MARKEND,這里我就不多說了。TRAPDsymbian里面經常使用的宏,功能類似于try,第一個參數(shù)是讓定義一個錯誤返回值變量的名字, 后面就是可能有異常的你寫的函數(shù).當這個函數(shù)異常時,程序不會crash, 你可以得到異常的原因.可以參考nokia論壇上的一些關于這些使用的文檔.

接下來是vcallInstanceL函數(shù),在這個函數(shù)里面我來建立ActiveScheduler.

LOCAL_C void callInstanceL()

{

    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();

    CleanupStack::PushL(scheduler);

    CActiveScheduler::Install(scheduler);

    TRAPD(error,doInstanceL());

    if(error)

    {

        printf("error code=%d\r\n",error);

    }

    else

    {

        printf("OK!\r\n[press any key]");

    }

    CleanupStack::PopAndDestroy(scheduler);

}

這段程序很簡單就是創(chuàng)建一個活動規(guī)劃器,并壓入清除棧,然后安裝活動規(guī)劃器,這樣就可以用了.再執(zhí)行真正的實例函數(shù),最后出棧銷毀。doinstance(該函數(shù)將在最后的代碼中給出,主要的功能就是調用我們自己寫的活動計數(shù)器)我們放到最后來寫,現(xiàn)在來構造我們的活動計數(shù)器對象。

class TimeCount : public CActive

{

public :

    static TimeCount* NewLC(); // 構造函數(shù)

    ~TimeCount();

    void StartL();             // 計數(shù)開始

    void ConstructL();

    void RunL();             // 延時事件到達以后的處理函數(shù)

    void DoCancel();         // 取消請求提交

    void setDelayTime(int delayTime);

private:

    TimeCount();

    RTimer iTimer;          // 定時器

    int iTimeCount;         // 計數(shù)器

     int mTime;            // 計數(shù)間隔時間 單位秒

};

 

TimeCount::TimeCount():CActive(0)  // 這里可以設置活動對象的優(yōu)先級

{

    // 把自己加入活動規(guī)劃器

    CActiveScheduler::Add(this);

}

 

TimeCount* TimeCount::NewLC()

{

    TimeCount* result = new (ELeave) TimeCount();

    CleanupStack::PushL( result );

    result->ConstructL();

    return result;

}

 

void TimeCount::DoCancel(void)

{

    iTimer.Cancel();

}

 

void TimeCount::setDelayTime(int mTime)

{

    DelayTime = mTime;

}

 

TimeCount::~TimeCount()

{

    Cancel();

    iTimer.Close();

}

 

void TimeCount::StartL()

{

    // 設定定時器狀態(tài)為每隔mTime秒鐘狀態(tài)完成一次

    iTimer.After(iStatus, 10000 * 100 * mTime);

    // 提交異步請求

    SetActive();

}

 

void TimeCount::ConstructL()

{

    // 初始化計數(shù)器和定時器

    iTimeCount = 0;

    User::LeaveIfError(iTimer.CreateLocal());

}

 

void TimeCount::RunL()

{

    // 計數(shù)器+1以后繼續(xù)提交延時請求事件

    printf("The Count is ->>%d", iTimeCount++);

    StartL();

}

每一個活動服務對象都有一個iStatus來標識當前對象的狀態(tài).在這里我們把iStatus設定為iTimer.After(iStatus, 10000 * 100 * mTime);也就是定時器定時mTime秒鐘以后iStatus發(fā)生改變,這個時候活動規(guī)劃器會收到這個狀態(tài)的改變,從而調用相應活動對象的處理函數(shù),也就是RunL函數(shù).RunL函數(shù)里面進行計數(shù)和輸出,然后調用startL重新設置定時器和對象狀態(tài),再提交給活動規(guī)劃器。這樣mTime秒鐘以后活動規(guī)劃器會再次調用RunL函數(shù).一直這樣重復,這樣就達到了計數(shù)器的效果。

最后我們來寫doinstanceL函數(shù)

LOCAL_C void doInstanceL()

{

    TimeCount* timeCount = TimeCount::NewLC();

    // 每隔一秒鐘打印一次

    TimeCount->setDelayTime(1);

    TimeCount->StartL();

    CActiveScheduler::Start();

    CleanupStack::PopAndDestroy(1);

}

創(chuàng)建好對象以后,加上CActiveScheduler::Start()程序就開始運行了,這句話告訴活動規(guī)劃器該等待對象的狀態(tài)的改變了(正常情況下,一旦CActiveScheduler::Start()之后,程序直到CActiveScheduler::Stop()才能終止運行),在這里就是timeCountiStatus的改變.iStatus改變并調用了RunL以后,繼續(xù)等待iStstus的改變,這樣我們使用活動對象的計數(shù)器就能夠通過消息驅動運行起來了.

這里的CActiveScheduler只管理了一個CActive對象,就是timeCount,可以用類似的方法實現(xiàn)多個CActive,并且都加入CActiveScheduler,CActiveScheduler將會等待所有加入它的CActive的狀態(tài)的改變,其中有一個的狀態(tài)改變就會去執(zhí)行對應的活動對象的處理函數(shù),當狀態(tài)同時發(fā)生的時候,會通過對象的優(yōu)先級來決定先調用誰的RunL函數(shù).CActiveScheduler也是非搶占式的,當一個RunL函數(shù)還沒有執(zhí)行完的時候,如果另一個CActive的狀態(tài)改變,會等待RunL執(zhí)行完以后再執(zhí)行另一個CActive的處理函數(shù)(正因為這一點,所以通常RunL函數(shù)不能設計為長函數(shù),否則會阻塞活動對象)

 本文在網上根據(jù)網上用人提供的原本閱讀學習而成,可算是轉載類型的。

 

 

posted @ 2008-10-11 21:03 frank.sunny 閱讀(2571) | 評論 (0)編輯 收藏

Active Object (AO) 框架,是Symbian的基本工作部分。它是為了滿足多個任務同時執(zhí)行的要求。在 Windows/Unix 平臺上,我們可以不加思索的使用多線程來完成多任務。可是在嵌入式平臺上,系統(tǒng)的資源是有限的。比如CPU、內存都比我們平時用的個人計算機要低。這就要求嵌入式系統(tǒng)能夠合理的使用系統(tǒng)資源。不能頻繁的切換線程或者進程。

Symbian為這種特別需求設計了Active Object (AO)框架。AO框架是運行于一個線程內部的調度框架。其基本思想就是把一個單線程分為多個時間片,來運行不同的任務

這和多線程有很大區(qū)別。多線程之間是可以被搶占的(由操作系統(tǒng)調度),但是AO框架中的各個任務是不可被搶占的,一個任務必須完成,才能開始下一個任務

下面是多線程和AO框架的簡單比較:

多線程                                       AO框架

可以被搶占                                   不可被搶占

上下文切換耗費CPU時間                       沒有上下文切換

由操作系統(tǒng)調度                               由線程自己的AO框架調度

每個線程都有至少4K Stack.                    AO沒有單獨的Stack.

操作系統(tǒng)還要分配額外的資源記錄線程            只是一個Active Object.

Symbian系統(tǒng)本身使用了大量的AO框架來實現(xiàn)一些系統(tǒng)服務。這使得Symbian和其他嵌入式系統(tǒng)相比較,對系統(tǒng)資源的使用更加合理。

AO框架包括CActiveScheduler CActive (Active Object)。一個線程的所有的Active Object對象都被安裝在該線程的CActiveScheduler對象內.CActiveScheduler對象監(jiān)控每個Active Object是否完成了當前任務,如果完成了,就調度下一個Active Object來執(zhí)行。CActiveScheduler根據(jù)優(yōu)先級來調度各個Active Object.

 

關于CActiveScheduler的創(chuàng)建和安裝,CActive的創(chuàng)建和安裝,和CActive的任務處理,可以參看 SDK 文檔。理解起來不難。下面要說一個比較容易忽略的地方。這對理解AO框架非常重要。

創(chuàng)建調度器:

CActiveScheduler * scheduler = new (ELeave) CActiveScheduler;

CleanupStack::PushL(scheduler);

CActiveScheduler::Install(scheduler);

 

運行調度器:

CActiveScheduler::Start();

 

停止調度器:

CActiveScheduler::Stop();

 

以上代碼都是運行在一個線程中的,一般來講,一個EXE只有一個主線程.

可是如果真的有2個線程呢?

為什么在當前線程下調用CActiveScheduler::Start(),CActiveScheduler::Stop()運行/停止的就是當前線程的調度器而不是另一個線程的調度器?

每個線程都有自己的CActiveScheduler,那么這個CActiveScheduler類是怎么調用CActiveScheduler::Start(),CActiveScheduler::Stop()來運行/停止當前的調度器的呢?

我們看到Start/Stop并沒有參數(shù).

打開CActiveScheduler的類定義:

class CActiveScheduler : public CBase

    {

public:

    IMPORT_C CActiveScheduler();

    IMPORT_C ~CActiveScheduler();

    IMPORT_C static void Install(CActiveScheduler* aScheduler);

    IMPORT_C static CActiveScheduler* Current();

    IMPORT_C static void Add(CActive* anActive);

    IMPORT_C static void Start();

    IMPORT_C static void Stop();

    IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);

    IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);

    IMPORT_C virtual void WaitForAnyRequest();

    IMPORT_C virtual void Error(TInt anError) const;

private:

    void DoStart();

    void OwnedStartLoop(TInt& aRunning);

    IMPORT_C virtual void OnStarting();

    IMPORT_C virtual void OnStopping();

    IMPORT_C virtual void Reserved_1();

    IMPORT_C virtual void Reserved_2();

private:

    // private interface used through by CActiveSchedulerWait objects

    friend class CActiveSchedulerWait;

    static void OwnedStart(CActiveSchedulerWait& aOwner);

protected:

    inline TInt Level() const;

private:

    TInt iLevel;

    TPriQue<CActive> iActiveQ;

    };

 

我們并沒有看到靜態(tài)的成員來表示線程,但是卻有一個static函數(shù)CActiveScheduler* Current();返回當前線程的調度器.

現(xiàn)在猜想奧秘就在這個函數(shù)是怎么實現(xiàn)的。這個靜態(tài)的函數(shù)怎么就能得到當前這個運行線程的調度器,而不是別的線程的調度器。我們可以猜想,肯定是Current()內部實現(xiàn)能取到當前線程的標識信息.用這個標識,靜態(tài)函數(shù)能取到這個線程的CActiveScheduler.這個具體如何實現(xiàn)呢?

答案就是:當前線程的線程ID可以這樣得到:

創(chuàng)建一個缺省的線程對象:

RThread thread;

取得當前線程的ID:

TThreadId threadId = thread.Id();

能得到當前線程的threadId,當然可以得到和當前線程關聯(lián)的CActiveScheduler。因此以上兩個問題也就迎刃而解了,在一個線程內調用CActiveScheduler::Start(),CActiveScheduler::Stop()開啟的就是當前線程。

既然回復了上面的問題,那么我們自然就能明確,在一個線程內是不能通過StartStop函數(shù)來開啟和停止另一個線程內的活動對象規(guī)劃器CActiveScheduler

 

補充點其他東西:

Symbian操作系統(tǒng)中,每個進程都有一個或多個線程。線程是執(zhí)行的基本單位。一個進程的主線程是在進程啟動時生成的。Symbian屬于搶占式多任務操作系統(tǒng),這意味著每個線程都有自己的執(zhí)行時間,直到系統(tǒng)將CPU使用權給予其他線程。當系統(tǒng)調度時,具有最高優(yōu)先權的線程將首先獲得執(zhí)行。

進程邊界是受內存保護的。所有的用戶進程都有自己的內存地址空間,同一進程中的所有線程共享這一空間,用戶進程不能直接訪問其他進程的地址空間。

每個線程都有它自己的stackheap,這里heap可以是私有的,也可以被其他線程共享。應用程序框架生成并安裝了一個active scheduler,并且為主線程準備了清除棧。如果沒有使用框架(如編寫exe程序)那就要手動生成這些了。

Symbian操作系統(tǒng)專為單線程應用優(yōu)化,因此強烈推薦使用“活動對象”代替多線程。

posted @ 2008-10-11 20:34 frank.sunny 閱讀(2699) | 評論 (2)編輯 收藏

 

如何在C++中調用C的代碼

 

以前曾經總結過一篇(http://m.shnenglu.com/franksunny/archive/2007/11/29/37510.html),關于在C中如何調用C++的代碼,當時并未做完全的展開,只是簡單的做了下調試,最近看到一個題目要求實現(xiàn)CC++中代碼的互相調用,其結果雖然都是通過extern “C”來實現(xiàn),但是具體還是有些差別的。

先對C中調用C++代碼作個簡單回顧:

1、              對于C++中非類的成員函數(shù),可以簡單的在函數(shù)聲明前面加extern “C”,通常函數(shù)聲明位于頭文件中,當然也可以將聲明和函數(shù)定義一起放在cpp,在沒有聲明的情況下,直接在定義前添加extern “C”也可

2、              對于C++類的成員函數(shù),則需要另外做一個cpp文件,將需要調用的函數(shù)進行包裝

以上兩項的實例參看前面C中如何調用C++代碼的文章。

要實現(xiàn)C++中調用C的代碼,具體操作:

對于C中的函數(shù)代碼,要么C代碼的頭文件進行修改,在其被含入C++代碼時在聲明中加入extern “C”或者C++代碼中重新聲明一下C函數(shù),重新聲明時添加上extern “C”

通過以上的說明,我明白一點,那就是extern “C”頭一定是加在C++的代碼文件中才能起作用的

 

下面分析一下這個現(xiàn)象的實質原因:

C編譯器編譯函數(shù)時不帶函數(shù)的類型信息,只包含函數(shù)符號名字,如C編譯器把函數(shù)int a(float x)編譯成類似_a這樣的符號,C連接器只要找到了調用函數(shù)的符號,就可以連接成功,它假設參數(shù)類型信息是正確的,這是C編譯連接器的缺點。而C++編譯器為了實現(xiàn)函數(shù)重載,編譯時會帶上函數(shù)的類型信息,如他把上面的a函數(shù)可能編譯成_a_float這樣的符號為了實現(xiàn)重載,注意它還是沒有帶返回值得信息,這也是為什么C++不支持采用函數(shù)返回值來區(qū)別函數(shù)重載的原因之一,當然,函數(shù)的使用者對函數(shù)返回值的處理方式(如忽略)也是重要原因。

基于以上,C調用C++,首先需要用封裝函數(shù)把對C++的類等的調用封裝成C函數(shù)以便C調用,于是extern "C"的作用是:讓編譯器知道這件事,然后C語言的方式編譯和連接封裝函數(shù)通常是把封裝函數(shù)用C++編譯器按C++方式編譯,用了extern "C" 后,編譯器便依C的方式編譯封裝接口,當然接口函數(shù)里面的C++語法還是按C++方式編譯;對于C語言部分--調用者,還是按C語言編譯;分別對C++接口部分和C部分編譯后,再連接就可以實現(xiàn)C調用C++)。相反,C++調用C函數(shù),extern "C" 的作用是:讓C++連接器找調用函數(shù)的符號時采用C的方式,即使用_a而不是_a_float來找調用函數(shù)。

 

具體示例請見http://m.shnenglu.com/Files/franksunny/CCallCpp.rar

注:如果你用VC6.0編譯附件時遇到類似“fatal error C1010: unexpected end of file while looking for precompiled header directive”報錯的話,請將bb.c文件做如下處理右鍵點擊項目工程中的該文件,選擇setting,在c/c++欄,選擇PreCompiled headers,然后設置第一選項,選擇不使用預編譯頭。

 

posted @ 2008-10-10 17:54 frank.sunny 閱讀(8996) | 評論 (1)編輯 收藏
     摘要:   活動對象框架原理   一、概述: Symbian OS是一個多任務的操作系統(tǒng),那么為了實現(xiàn)多任務,同時使系統(tǒng)能夠快速響應,高效的進行事件處理,并減輕應用程序員的工作負擔(申請大多數(shù)耗時的操作(例如文件系統(tǒng))由服務提供器來完成,服務提供器完成程序員提交的請求后,將會返回給程序員一個成功或失敗的信號。),Symbian OS特意引入了活動對象的概念。 服務提供器API...  閱讀全文
posted @ 2008-10-09 20:42 frank.sunny 閱讀(1829) | 評論 (0)編輯 收藏

這種在Symbian C/S架構中,服務器程序與客戶UI進程主動通信中用的比較多。

對于在往UI框架應用程序發(fā)送消息,可以通過Symbian OSApplication Architecture Services可以進行應用程序間的通信,主要用到的類包括:TApaTaskListTApaTask

TApaTaskList:用于訪問設備中正在運行的任務(假如有些任務隱藏了的話,那么通過這種方法也無法進行訪問)。

TApaTask:表示設備中某個運行的任務,通過與程序關聯(lián)的窗口組(window group)標識。

具體的解決方案:

發(fā)送消息端:使用TApaTaskList找到等待接收消息的任務,TApaTaskList::FindApp()提供了兩個重載版本,可以使用程序的標題,也可以使用程序的UID進行查找。獲得需要發(fā)消息的任務后就可以通過TApaTask:: SendMessage()發(fā)送消息了,它有兩個參數(shù),第一個參數(shù)用于標識消息,第二個參數(shù)是一個描述符的引用,可以用來提供不同消息時附加的具體信息。

TUid uid( TUid::Uid( 0x0116C9D3 ) );

TApaTaskList taskList( iCoeEnv->WsSession() );

TApaTask task = taskList.FindApp(uid );

 

if( task.Exists() ) //判斷任務是否正在運行

{

    LIT8( KTestMsg, "CustomMessage" );

    TUid msgUid( TUid::Uid( 1 ) );

    task.SendMessage( uid, KTestMsg );

}

 

接收消息端可以使用如下兩種方案:

第一種方案:由于MCoeMessageObserver是處理來自窗口服務器消息的接口類,而CEikAppUi已經繼承自MCoeMessageObserver,所以我們只需要在自己的UI類中重現(xiàn)實現(xiàn)MCoeMessageObserver的唯一成員函數(shù)HandleMessageL()用來處理接收到的消息即可,代碼如下:

MCoeMessageObserver::TMessageResponse CXXXAppUi::HandleMessageL(TUint32 aClientHandleOfTargetWindowGroup, TUid aMessageUid, const TDesC8& aMessageParameters)

{

    _LIT( KFormatStr, "%x" );

    TBuf<32> bufUid;

    TBuf<32> bufPara;

    bufUid.AppendFormat( KFormatStr, aMessageUid.iUid );

    bufPara.Copy( aMessageParameters );

    iEikonEnv->InfoWinL( bufUid, bufPara );

    return MCoeMessageObserver::EMessageHandled;

}

 

第二種方案:由于TApaTask::SendMessage()發(fā)送的消息可以被CEikAppUI的成員函數(shù)ProcessMessageL()攔截并處理,不過必須在沒有重載HandleMessageL()函數(shù)的前提下,而且函數(shù)ProcessMessageL()只負責攔截消息標識為KUidApaMessageSwitchOpenFileValueKUidApaMessageSwitchCreateFileValue的這兩個消息,其它標識值的消息不會被傳到ProcessMessageL()中,所以這種方案個人覺得很受限制,不自由,還是采用第一種方案好,具體代碼代碼如下:

//發(fā)送:

TUid uid( TUid::Uid( 0x0116C9D3 ) );

TApaTaskList taskList( iCoeEnv->WsSession() );

TApaTask task = taskList.FindApp(uid );

 

if( task.Exists() ) //判斷任務是否正在運行

{

    LIT8( KTestMsg, "CustomMessage" );

    //這里的Uid不能使用自定義的,而且只有系統(tǒng)提供的兩個

    TUid msgUid( TUid::Uid(KUidApaMessageSwitchCreateFileValue) );

    task.SendMessage( uid, KTestMsg );

}

 

//接收:

void CXXXAppUi::ProcessMessageL(TUid aUid,const TDesC8& aParams)

{

    RFileLogger iLog;

    iLog.Connect();

    iLog.CreateLog(_L("tb"), _L("UpdateListener2.txt"), EFileLoggingModeOverwrite);

    iLog.Write(_L("smms appui"));

 

    if (aUid.iUid == KUidApaMessageSwitchCreateFileValue)

    {

        TBuf<256> buf;

        buf.Copy(aParams);

        iLog.Write(aParams);

        BringMeToFront();

        ShowCreateFile(buf,CFileMonitorEngine::EImageType);

    }

    else

    {

        CAknViewAppUi::ProcessMessageL(aUid,aParams);

    }

    iLog.Close();

}


明天就是中秋了,恭祝大家中秋節(jié)快樂
posted @ 2008-09-13 07:46 frank.sunny 閱讀(2088) | 評論 (1)編輯 收藏
     摘要:   關于vCard和Symbian上的操作   前陣子關于Symbian通訊錄操作的時候曾提到vCard,但是由于當時項目比較緊,所以也沒有時間整理,今天特意抽了點時間小試了一下,發(fā)現(xiàn)很多手機(我試了下索愛的和諾基亞的)如果選中通訊錄中的記錄發(fā)送聯(lián)系人或者發(fā)送名片之類的操作,就是會以vcf文件格式進行發(fā)送。不過手機上的vcf文件通常是用UTF-8編碼的,所以雖然可以用ou...  閱讀全文
posted @ 2008-09-13 07:20 frank.sunny 閱讀(3730) | 評論 (0)編輯 收藏
     摘要: Symbian OS平臺簡體漢字編程編碼處理   相信大家都在處理symbian中文顯示的時候遇到了編碼的問題,我現(xiàn)在就給總結一下這種問題的解決方法: 字符串編碼中文表示常用的有:GB2312,GBK,Unicode,UTF-8 其中GBK是GB2312的超集,也就是涵蓋了GB2312編碼的所有內容; UTF-8是Unicode的在網絡傳輸中的一種編碼格式。 如果我們使用...  閱讀全文
posted @ 2008-09-10 20:11 frank.sunny 閱讀(4146) | 評論 (1)編輯 收藏
     摘要: Symbian OS中的消息存儲與常用操作 說明:本文前面消息的基本知識主要參考《Series60應用程序開發(fā)》中的有關內容,后面是前段做MTM開發(fā)中用到的代碼。 一、消息存儲基本知識 Symbian OS提供的消息傳送架構基于Client/Server機制,服務器負責管理手機上的各種消息,在進行消息相關操作之前我們需要了解Symbian OS是如何組織和存儲消息的。 手機中的各種消息...  閱讀全文
posted @ 2008-07-30 21:04 frank.sunny 閱讀(3266) | 評論 (2)編輯 收藏
     摘要:   Symbian OS應用開發(fā)學習筆記之通訊錄(電話薄Contacts)   Symbian OS通訊錄模型 Symbian OS手機的通訊錄采用文件方式存儲,用symbian自己的說法就是通訊錄數(shù)據(jù)庫。每個Symbian OS手機都有一個默認的通訊錄數(shù)據(jù)庫,這個通訊錄數(shù)據(jù)庫在2nd和3rd兩個版本手機中的位置是不同的,前者是c:\ system\data\Conta...  閱讀全文
posted @ 2008-06-27 08:05 frank.sunny 閱讀(6449) | 評論 (8)編輯 收藏

 

今天接到電話面試,被問到幾個問題,汗顏之余,小結一下

1、      多態(tài)是如何實現(xiàn)綁定的

多態(tài)的綁定可以分為運行是多態(tài)和編譯時多態(tài)

編譯時的多態(tài)性

編譯時的多態(tài)性是通過重載來實現(xiàn)的。對于非虛的成員來說,系統(tǒng)在編譯時,根據(jù)傳遞的參數(shù)、返回的類型等信息決定實現(xiàn)何種操作。

運行時的多態(tài)性

運行時的多態(tài)性就是指直到系統(tǒng)運行時,才根據(jù)實際情況決定實現(xiàn)何種操作。C#中,運行時的多態(tài)性通過虛成員實現(xiàn)。

編譯時的多態(tài)性為我們提供了運行速度快的特點,而運行時的多態(tài)性則帶來了高度靈活和抽象的特點。

今天才正式弄清楚原來虛函數(shù)是可以實現(xiàn)運行時多態(tài)的,以前只知道虛函數(shù)可以使得基類對象的的方法調用派生類的方法。

2、      析構函數(shù)是虛函數(shù)的優(yōu)點是什么

C++開發(fā)的時候,用來做基類的類的析構函數(shù)一般都是虛函數(shù)。可是,為什么要這樣做呢?下面用一個小例子來說明:

有下面的兩個類:

class ClxBase

{

public:

    ClxBase() {};

    virtual ~ClxBase() {};

 

    virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };

};

 

class ClxDerived : public ClxBase

{

public:

    ClxDerived() {};

    ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };

 

    void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };

};

 

代碼

 

ClxBase *pTest = new ClxDerived;

pTest->DoSomething();

delete pTest;

 

輸出結果是:

 

Do something in class ClxDerived!

Output from the destructor of class ClxDerived!

 

這個很簡單,非常好理解。

但是,如果把類ClxBase析構函數(shù)前的virtual去掉,那輸出結果就是下面的樣子了:

Do something in class ClxDerived!

也就是說,類ClxDerived的析構函數(shù)根本沒有被調用!一般情況下類的析構函數(shù)里面都是釋放內存資源,而析構函數(shù)不被調用的話就會造成內存泄漏。我想所有的C++程序員都知道這樣的危險性。當然,如果在析構函數(shù)中做了其他工作的話,那你的所有努力也都是白費力氣。

所以,文章開頭的那個問題的答案就是--這樣做是為了當用一個基類的指針刪除一個派生類的對象時,派生類的析構函數(shù)會被調用。

當然,并不是要把所有類的析構函數(shù)都寫成虛函數(shù)。因為當類里面有虛函數(shù)的時候,編譯器會給類添加一個虛函數(shù)表,里面來存放虛函數(shù)指針,這樣就會增加類的存儲空間。所以,只有當一個類被用來作為基類的時候,才把析構函數(shù)寫成虛函數(shù)。

 

說實話,這個也是今天才深刻認識到的。

 

當然還問到很多數(shù)據(jù)結構和算法方面(空間復雜度和時間復雜度之類的東東,說真的也是基礎性的)的問題,至于那些東西,自己說實話拋開沒用他們已經很長時間了,真可以說忘的差不多了,考這種真的很怕,也怪平時沒怎么用到。不知道大家用的多不?

好久沒有正式參加過面試了,今天突然來一次覺得自己基礎還是不夠扎實。

posted @ 2008-05-19 20:30 frank.sunny 閱讀(18165) | 評論 (12)編輯 收藏
僅列出標題
共7頁: 1 2 3 4 5 6 7 

常用鏈接

留言簿(13)

隨筆分類

個人其它博客

基礎知識鏈接

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲美女精品久久| 国内一区二区三区| 亚洲一区在线播放| 国产偷国产偷精品高清尤物| 亚洲一区二区三区在线看| 99国内精品| 一区二区三区|亚洲午夜| 一区二区三区精品国产| 亚洲欧美日韩精品综合在线观看| 亚洲一区欧美二区| 久久国产精品久久久久久| 欧美一区二区三区视频在线观看| 久久久久久久久岛国免费| 亚洲视频在线观看| 一区二区日韩伦理片| 亚洲一区二区三区精品在线 | 欧美网站大全在线观看| 国产精品久久久久毛片软件| 国外成人在线| 一区二区三区久久久| 欧美专区18| 亚洲国产第一| 你懂的网址国产 欧美| 亚洲国产精品美女| 亚洲欧美另类在线观看| 99视频在线观看一区三区| 销魂美女一区二区三区视频在线| 欧美影院一区| 欧美国产日韩亚洲一区| 国产精品高潮呻吟| 尤物网精品视频| 中国女人久久久| 久久亚洲精品欧美| aa国产精品| 久久综合久久美利坚合众国| 欧美午夜精品久久久| 亚洲国产日韩欧美| 久久国产婷婷国产香蕉| 一本久久知道综合久久| 欧美成人乱码一区二区三区| 国产一区视频网站| 午夜亚洲性色视频| 亚洲美女电影在线| 欧美国产日产韩国视频| 在线视频观看日韩| 久久视频在线看| 亚洲欧美日韩国产成人| 欧美日韩精品免费观看视一区二区 | 国产亚洲激情视频在线| 美女精品视频一区| 国产精品影院在线观看| 亚洲视频高清| 亚洲三级视频| 欧美夫妇交换俱乐部在线观看| 悠悠资源网久久精品| 久久深夜福利免费观看| 欧美一级二区| 国产亚洲人成a一在线v站| 亚洲一区日韩在线| 9国产精品视频| 欧美日韩精品在线| 亚洲私人影吧| 一区二区精品国产| 国产精品久久久久久久app| 中国女人久久久| 99热在这里有精品免费| 欧美午夜一区二区福利视频| 亚洲午夜视频在线观看| 一本大道久久精品懂色aⅴ| 欧美性片在线观看| 亚洲欧美国产一区二区三区| 亚洲一区二区三区精品视频| 国产欧美精品一区二区三区介绍 | 牛牛精品成人免费视频| 久久www成人_看片免费不卡| 狠狠网亚洲精品| 猛干欧美女孩| 欧美插天视频在线播放| 中文精品一区二区三区| 亚洲色无码播放| 国产一区二区激情| 欧美成人乱码一区二区三区| 蜜臀av性久久久久蜜臀aⅴ四虎| aa级大片欧美三级| 亚洲在线成人| 亚洲第一在线综合在线| 亚洲美女诱惑| 国产美女一区| 欧美大胆a视频| 国产精品久久久久aaaa樱花| 久久婷婷麻豆| 欧美日本不卡视频| 久久九九免费| 欧美日本免费| 久久国产精品一区二区三区| 欧美 亚欧 日韩视频在线| 亚洲欧美国产va在线影院| 欧美国产日产韩国视频| 伊人蜜桃色噜噜激情综合| 亚洲美洲欧洲综合国产一区| 国内一区二区在线视频观看 | 欧美一级视频免费在线观看| 亚洲欧洲日本mm| 午夜免费久久久久| 一区二区国产在线观看| 亚洲福利视频网| 久久久99国产精品免费| 一区二区三区国产盗摄| 久久国产精品久久精品国产| 夜夜嗨av一区二区三区网页| 欧美在线观看视频一区二区三区| 日韩视频不卡中文| 久久精品成人欧美大片古装| 亚洲一区二区日本| 欧美激情欧美狂野欧美精品| 久久久久综合一区二区三区| 欧美图区在线视频| 亚洲欧洲视频| 亚洲国产精品精华液2区45| 欧美亚洲系列| 午夜久久久久久| 欧美日韩精品高清| 亚洲国产综合视频在线观看| 激情久久久久久| 午夜天堂精品久久久久| 亚洲男人的天堂在线aⅴ视频| 免费久久99精品国产| 美女日韩在线中文字幕| 国产性天天综合网| 亚洲视屏一区| 午夜老司机精品| 国产精品美女诱惑| 亚洲线精品一区二区三区八戒| 99精品视频免费观看视频| 欧美成人在线免费观看| 亚洲国产高清在线| 日韩一级大片在线| 欧美伦理a级免费电影| 亚洲精品在线观看免费| 在线亚洲自拍| 国产精品国产福利国产秒拍| 夜夜嗨一区二区三区| 亚洲欧美美女| 国产一区二区三区无遮挡| 久久国产精品黑丝| 快she精品国产999| 亚洲成色精品| 免费日本视频一区| 亚洲人成人一区二区三区| 99视频在线精品国自产拍免费观看 | 蜜臀av在线播放一区二区三区| 激情久久中文字幕| 欧美不卡视频一区| 亚洲乱码国产乱码精品精| 亚洲在线成人精品| 国产日韩欧美在线看| 久久成人人人人精品欧| 欧美激情国产日韩| 一区二区不卡在线视频 午夜欧美不卡' | 亚洲欧美日韩国产中文| 国产精品女主播一区二区三区| 在线视频精品| 久久―日本道色综合久久| 91久久国产综合久久| 欧美日韩综合在线| 久久成人一区二区| 亚洲国产精品一区二区久| 亚洲尤物精选| 在线观看日韩一区| 国产精品v日韩精品| 性做久久久久久久久| 亚洲欧美激情在线视频| 免费久久99精品国产自| 99精品欧美一区二区三区综合在线 | 久久成人精品电影| 亚洲福利视频三区| 欧美一二三视频| 亚洲高清免费在线| 欧美三级午夜理伦三级中视频| 久久不射网站| 亚洲视频导航| 亚洲国产精品久久久久久女王| 午夜精品久久久久久久99热浪潮 | 在线精品一区| 国产精品九九久久久久久久| 久久精品视频导航| 日韩亚洲视频在线| 欧美阿v一级看视频| 午夜亚洲影视| 在线亚洲伦理| 亚洲三级免费观看| 国产亚洲精品久久久久婷婷瑜伽| 欧美精品激情blacked18| 亚洲欧美日韩精品久久| 亚洲精品一区二区三区樱花 | 亚洲一区二区三区高清不卡| 一区二区三区在线观看国产| 欧美午夜精品久久久久久孕妇| 久久久最新网址| 久久国产精品久久国产精品|