C++模板成员对象

C++ template member object

本文关键字:成员对象 C++      更新时间:2023-10-16

我遇到了一个问题,一个设计问题。有这个模板类,它表示文件处理/驱动程序接口。这是该类的准系统。

---------------------------- 文件驱动程序.h---------------------------

namespace DatabaseManager {
template<class T>
class FileDriver {
FileDriver(const char *file_name) : file_name(file_name) {}
public : 
T* fetch(size_t rec_size, long rec_num, long offset , bool write_enabled) {
// fetch data from file
}
int insert(T *rec, size_t rec_size, long rec_num, long offset) {
// insert data into file
}
inline int release(T *rec, size_t rec_size, int rec_num) {
 // close the file
}
};
}

现在,系统中的任何需要 I/O 操作的类都使用此类。但由于它是一个模板类,所以我每次需要访问文件时都必须创建此类的对象。例如,下面是函数如何使用此类。

 ---------------------- ParseSparseParticles.cpp ------------------
     #include "FileDriver.h"
     bool ParseSparseParticles::openFile() throw(ParseSparseParticlesException)
    {
       // DatabaseManager::FileMetaInfo is a struct containing meta information about a file
      DatabaseManager::FileMetaInfo *meta_info = nullptr;
      DatabaseManager::SparseParticles *particle_data = nullptr; 
      DatabaseManager::FileDriver<DatabaseManager::FileMetaInfo> meta_hndlr(meta_file_name.str().c_str());
      meta_info = meta_hndlr.fetch(sizeof(DatabaseManager::FileMetaInfo), 1, static_cast<int>(DatabaseManager::file_map_pos::START), false);
      if (meta_info) {
        DatabaseManager::FileDriver<DatabaseManager::SparseParticles> data_hndlr(file_name.str().c_str());
        particle_data = data_hndlr.fetch(sizeof(DatabaseManager::SparseParticles),
                                   meta_info->num_rec, static_cast<int>(DatabaseManager::file_map_pos::START), false);
        if (particle_data) {
          data_hndlr.release(particle_data, sizeof(DatabaseManager::SparseParticles), meta_info->num_rec);
          meta_hndlr.release(meta_info, sizeof(DatabaseManager::FileMetaInfo), 1);
          return true;
        } else {
          throw ParseSparseParticlesException("Cannot open Sparse Particles File");
        }
      } else {
        throw ParseSparseParticlesException("Cannot open Meta Info File");
      }
    }

因此,每次需要访问任何文件时,我都必须遵循完全相同的步骤。1. 打开元信息文件2.打开实际数据文件3. 关闭数据文件4. 关闭元文件

一段时间后,这变得很烦人,更糟糕的是,它会导致重复代码,非结构化代码,因为文件操作在整个系统中完成。所以我在考虑制作一个接口来抽象 I/O 的操作。在这样做的过程中,当我想创建接口类的FileDriver成员对象时,我磕磕绊绊了,就像这样

    --------------------------- IOInterface.h ---------------------------

    #include "FileDriver.h"
    template<typename MetaFileType, typename FileType>
    class IOInterface {
    DatabaseManager::FileDriver<MetaFileType> meta_orb; // won't compile 
    DatabaseManager::FileDriver<FileType> data_orb; // won't compile
    };

但这不会编译,因为我将模板标头包含在另一个模板标头中。所以可以请任何人告诉我如何解决这个问题。我怎样才能创建一个类,该类将充当FileDriver的接口,只要该类对象处于活动状态,该类就会存储FileDriver对象。

谢谢

更新

我在编译时遇到的错误是使用 IOInterface 构造函数。

IOInterface::IOInterface(std::string data_dir, std::string file_prefix, int id) :
  data_dir(data_dir),
  file_prefix(file_prefix),
  file_id(id)
{}
/var/local/PolymerizationSimulation/include/IOInterface.h:7: error: no matching function for call to 'DatabaseManager::FileDriver<DatabaseManager::MetaFileType>::FileDriver()'
/var/local/PolymerizationSimulation/include/IOInterface.h:7: error: no matching function for call to 'DatabaseManager::FileDriver<DatabaseManager::FileType>::FileDriver()'
查看

代码的一些提示:

您在类定义后错过了分号:

};
 ^

同样从您的示例中,FileDriver 不在 DatabaseManager 中

在本课程中:

template<class T>
    class FileDriver {

所有成员都是私有的,甚至是构造函数,因此您无法访问它。最后,此类不提供以下人员所需的默认构造函数:

DatabaseManager::FileDriver<MetaFileType> meta_orb; // won't compile 
DatabaseManager::FileDriver<FileType> data_orb; // won't compile

所以编译器不知道如何创建这些实例,为FileDriver添加它:

FileDriver(){}