0

标题很长,但我想不出如何使它更简洁。真正问这个问题也是如此。不幸的是,我真的不知道问我想要的问题的正确词,所以我希望如果我能描述它,有人会知道我想问什么......


基本上,我正在构建一个游戏,并有各种类用于读取和写入各种类型的文件。配置文件、保存的游戏、资产包等。对于资产包(模型、声音等)的示例,我有一个 AssetPackReader 类和一个 AssetPackWriter 类,它们分别使用 ifstream 和 ofstream 对象。目前课程不完整,仅展示基本理论。

class AssetPackWriter
{
protected:
    unsigned int FilesToAddOnCommit;
    std::string * NewFileCommitList;
    AssetPackStruct AssetPackData;
    std::ofstream * AssetPackFileStream;
    bool ChangesSaved;
public:
    AssetPackWriter(std::ofstream * OutputFileStream)
    {
        AssetPackFileStream = OutputFileStream;
        ChangesSaved = false;
    }
    virtual ~AssetPackWriter()
    {
        if(!ChangesSaved) Save();
    }
    void AddFile(std::string FileName);
    virtual void Save(void); //Perform full save
};//The writer only writes new files (overwriting ones that already exist)

class AssetPackReader
{
protected:
    AssetPackStruct AssetPackData;
    std::ifstream * AssetPackFileStream;
public:
    AssetPackReader(std::ifstream * InputFileStream)
    {
        AssetPackFileStream = InputFileStream;
    }
    unsigned long long FindFile(std::string FileNameWithPath);
    void ExtractFile(unsigned long long FileEntry, CryptoPP::BufferedTransformation * OutputSink = 0);
    //First 4 bytes = Folder name index
    //remaining 4 bytes = file name index

    //When the game extracts something, the extract output will be an ArraySink into memory
    //but when invoked from command line, the extract output can either be an existing FileSink, or left blank to create a file on the hard disk of the same name

    void ListContents(CryptoPP::BufferedTransformation * OutputSink = 0); //If output is left blank it will be to a string sink which prints to stdout.
};//The reader only reads existing files (read only - no adding new files to an existing archive)

现在我想创建一个具有两者功能的类。这样可以:

  • 从头开始创建一个新包(如作者),
  • 打开一个已经存在的包(如阅读器),
  • 向包中添加更多资产,要么
    • 无需从头开始重写(速度较慢)
    • 从头开始重写它(这应该使文件更快地阅读)

用户可能更喜欢从头开始重写(FullSave),因为不修改现有的打包数据意味着需要第二个目录(如果没有超级优化,在目录之间查找时效率要低得多)。

虽然此 FullSave 应该使读取文件更快一些(不确定多少),但它比 FastSave 花费的时间要长得多,尤其是在修改的现有存档已经相当大的情况下。

所以,这是我尝试使用多重继承来创建这样一个包含每个超类的读写操作的类。对我来说,这听起来比复制和粘贴 reader 和 writer 类的功能更有效,但我显然不太了解某些东西......

class AssetPackageManager: public AssetPackWriter, public AssetPackReader
{
protected:
    std::fstream * AssetPackFileStream;
    bool DefaultFastSave;
public:
    AssetPackageManager(std::fstream * PackageFileStream) : AssetPackWriter(PackageFileStream), AssetPackReader(PackageFileStream)
    {
        DefaultFastSave = true;
    }
    ~AssetPackageManager()
    {
        Save();
    }
    void Save(void); //Overrides inherited function. AssetPackWriter::Save can only perform a FullSave, because it always starts with an empty file.
    //The default for a AssetPackageManager is the FastSave, which only adds new data to the end
    void FullSave(void)
    {
        AssetPackWriter::Save();
        //Rewrites the entire asset package (and all uncommitted changes) from scratch.
    }
    void FastSave(void); //Adds uncommitted changes to the end of the existing file
}; //The packager can write new files, and read (and update) existing files (new files can be added to an existing archive)

如您所见,我已经更改了每个基类中的 ifstream 和 ofstream 对象,并用 fstream 替换了它们,但现在有些东西告诉我,我走上了死胡同。

如果 reader 类中的 ExtractFile 函数采用 ifstream,它(当由包管理器类继承时)可以使用 fstream 吗?

我认为多重继承是正确的方法,因为: ifstream 从 istream 继承 ofstream 从 ostream 继承 fstream 从 iostream 继承(而后者又从 istream 和 ostream 乘以继承)

...但是我只是不确定了,尤其是因为我在包管理器构造函数中遇到错误...它说类型(ifstream 和 ofstream 与 fstream)不相关,但我认为它们是.. .

error C2664: 'AssetPackWriter::AssetPackWriter(std::ofstream *)' : cannot convert parameter 1 from 'std::fstream *' to 'std::ofstream *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

error C2664: 'AssetPackReader::AssetPackReader(std::ifstream *)' : cannot convert parameter 1 from 'std::fstream *' to 'std::ifstream *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
4

0 回答 0