2012-05-24 85 views
0

問題如何擴展庫類的功能?

我建我的Unicode的項目,但我需要的CMyDoc ::序列化()函數來讀取ASCII /寫文件(思字符串)。問題是,一旦在Unicode中,CArchive類自動讀取/寫入Unicode中的所有字符串以及我不想要的。

我的解決方案

我的解決辦法是派生我自己的類CArchiveACArchive支持ASCII字符串爲好。這是我的班級定義。

class CArchiveA : public CArchive 
{ 

public: 
    CArchiveA(CFile* pFile, 
       UINT nMode, 
       int nBufSize = 4096, 
       void* lpBuf = NULL); 

    CArchiveA(CArchive & ar); 

    virtual ~CArchiveA(); 

    BOOL ReadStringA(CStringA& rString); 
    LPSTR ReadStringA(_Out_z_cap_(nMax+1) LPSTR lpsz, _In_ UINT nMax); 

    void WriteStringA(LPCSTR lpsz); 


}; 

現在我希望做的文檔的文件Serialize功能這樣的事情。

void CTestDoc::Serialize(CArchive& ar) 
{ 
    CArchiveA & ar_a (ar); 

    // text is of type CStringA 

    if (ar.IsStoring()) 
    { 
     // TODO: add storing code here 
     ar_a.WriteStringA(text); 
    } 
    else 
    { 
     // TODO: add loading code here 

     ar_a.ReadStringA(text); 
    } 
} 

但上面第一行CArchiveA & ar_a (ar);是編譯器錯誤。

問題

也許我只是感覺今天生鏽,但我怎麼能轉換CArchive我自己的派生類CArchiveA,所以我可以使用它?如果我不是從CArchive派生出來的,而是寫一些幫助函數,它會接受CArchive作爲第一個參數並寫入ASCII字符串,這會更好嗎?

我發現這是一個有趣的案例研究,擴展了給定庫中基類的功能。我很想在解決方案中探索這方面,同時尋找面向對象的設計。我有我的想法,但首先想聽你的想法。從這個意義上說,問題的解決方式是什麼時候解決這樣的問題的最好方法是什麼時候(比如說)庫類的功能降低了?謝謝。

回答

1

我認爲遏制是比這項工作繼承更好的工具。

通過公有繼承,你在說CArchiveA是-。

這種關係是不可交換的。這與親子關係類似。因此,CArchive對象不是 a CArchiveA對象,並且不能使用CArchiveA參考指向CArchive對象。

一個更好的選擇是讓你的CArchiveA類包圍CArchive對象,幷包含它而不是從它繼承。您可以爲CArchiveA定義一個構造函數,該構造函數接受CArchive對象或引用,並保留對其的引用,然後定義您的方法以執行所需操作。

如果CArchive實現了一些抽象接口,您也可以從中得到CArchiveA。但是,如果沒有,你可能不希望爲此使用繼承。

+0

這是一個好方法。當我嘗試'CTestDoc :: Serialize(CArchiveA&ar)'時,該函數不再被框架調用,所以這說明了'CArchive'不是'CArchiveA' – zar