通过模板或纯虚拟基类继承动态类型文件访问?

Posted

技术标签:

【中文标题】通过模板或纯虚拟基类继承动态类型文件访问?【英文标题】:Dynamically typed file access via templates or pure virtual base class inheritance? 【发布时间】:2012-03-07 10:57:34 【问题描述】:

我想访问一个包含各种类型的键-值对的文件(例如,目前只有double,但将来可能是long double)。 文件访问可能发生在键之间,此时将进行一些(相当复杂的)插值。访问速度非常重要。

我看到了两种可能的实现方式:

    使用 模板 为这种类型的文件编写通用阅读器,使用键和值类型作为模板参数。这将非常快速且易于实现,但是,它需要人们在打开文件时知道文件中的类型。 要在不知道确切类型的情况下打开文件,我需要实现一个包装器,打开各种类型的文件并转换类型,这意味着每次访问文件时都会进行几次转换。 缺点是这个包装器会非常丑陋和庞大,因为它必须为每个可能的类型组合包含一个特殊情况。我可能会为这个包装器自动生成代码或使用一些预处理器魔法。 从计算机科学的角度来看,使用通用抽象基类将键和值类型包装到类中并始终处理指向这些类的指针会更好。 这将使未知类型文件的使用变得更加容易,尽管它始终涉及动态转换。 问题是前面提到的插值将需要构建大量的这些包装类以及大量的虚函数调用,这可能会对访问速度产生显着的负面影响。 我也犹豫要不要添加这种没人会使用的灵活性(毕竟,double 是现在唯一需要的东西)。

你会怎么做?你有更好的建议吗?

【问题讨论】:

【参考方案1】:

看看工厂设计模式。在工厂中,您将传递文件的标题 -> 类型,它将为此文件生成一个阅读器。所以你必须定义一个接口 IFile 并在你的类 PdfFile、TxtFile、DocxFile 等中实现它。

您可以使用抽象工厂或工厂方法取决于您的要求 我给你举个抽象工厂的例子:

class IFileFactory
public:
 virtual IFile* getInstance( const std::string& fileHeader ) = 0; //header in hex representation.
;

class ConcreteFileFactory : public IFileFactory
 IFile* getInstance( const std::string& fileHeader )
    if( fileHeader == "33442233" )
    
       return new PdfFile();
    else if( fileHeader == "4455533" )
       return new DocxFile();
    
    //......
    throw FactoryException("Unknown file");
 
;

【讨论】:

是的,这里的关键是在文件中有一个标题,以显示用于实例化其余部分的阅读器的类型。您可以使用工厂模式,但不是必须的。 (但你应该!!):) 嗯,是的,谢谢,这就是我想围绕模板化设计实现包装器的方式。所以你会去模板化设计并使用工厂模式编写一个包装器?

以上是关于通过模板或纯虚拟基类继承动态类型文件访问?的主要内容,如果未能解决你的问题,请参考以下文章

6多态性-3虚函数

在模板基类中为继承类中的可选覆盖生成虚拟方法

Item 43:访问模板基类中的名称 Effective C++笔记

访问者:通过继承添加更多类型

c++重用和模板

C++ VS代码爆红:不允许对不可访问的基类进行转换(子类继承父类时必须加上继承属性,比如public)