如何扩展库类的功能

How to extend functionality of a library class?

本文关键字:功能 扩展 何扩展      更新时间:2023-10-16

>问题

我用Unicode构建我的项目,但我需要CMyDoc::Serialize()函数来读取/写入ASCII中的文件(想想字符串)。问题是一旦进入Unicode,CArchive类会自动读取/写入Unicode中的所有字符串,这也是我不想要的。

我的解决方案

我的解决方案是从也支持 ASCII 字符串的 CArchive 派生我自己的类CArchiveA。这是我的类定义。

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 字符串的帮助程序函数,会更好吗?

我发现这是一个有趣的案例研究,从给定库扩展基类的功能。我很想在寻找面向对象设计的同时在解决方案中探索这一方面。我有我的想法,但想先听你说。从这个意义上说,问题是,当(比如)库类的功能有点不足时,解决此类问题的最佳方法是什么?谢谢。

我认为对于这项工作来说,遏制是比继承更好的工具。

通过公共继承,您是在说CArchiveACArchive

这种关系不是可交换的。 这类似于亲子关系。 因此,CArchive对象不是CArchiveA对象,并且不能使用 CArchiveA 引用指向CArchive对象。

更好的选择是使CArchiveA类成为CArchive对象的包装器,并包含它而不是从它继承。 您可以为 CArchiveA 定义一个构造函数,该构造函数接受CArchive对象或引用,并保留对它的引用,然后定义ReadString/WriteString方法来执行所需的操作。

如果CArchive实现了某个抽象接口,您可能还希望从中派生CArchiveA。 但如果没有,您可能不想为此使用继承。