如何扩展库类的功能?

Posted

技术标签:

【中文标题】如何扩展库类的功能?【英文标题】:How to extend functionality of a library class? 【发布时间】:2012-05-24 15:51:59 【问题描述】:

问题

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

我的解决方案

我的解决方案是从CArchive 派生我自己的类CArchiveA,它也支持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 是-a CArchive

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

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

如果CArchive 实现了一些抽象接口,您可能还想从中派生CArchiveA。但如果不是,您可能不想为此使用继承。

【讨论】:

这是一个很好的表达方式。当我尝试 `CTestDoc::Serialize(CArchiveA& ar)' 时,该函数将不再被框架调用,所以这说明了 CArchive is not CArchiveA

以上是关于如何扩展库类的功能?的主要内容,如果未能解决你的问题,请参考以下文章

Sonata 管理包,如何使用实体存储库类

如何抵御社工库类的黑客攻击?在明文密码已泄露的情况下保护自己?

Flutter/Dart JSON 和现有库类的序列化

学习 Kotlin - 扩展函数

打字稿与实现接口一起扩展类

PHP的SPL扩展库函数