0

長いタイトルですが、これ以上簡潔にする方法が思いつきません。実際に実際に質問する場合も同じです。残念ながら、私は自分が聞きたい質問をする正しい言葉を本当に知らないので、それを説明できれば、誰かが私が尋ねようとしていることを知ってくれることを願っています...


基本的に、私はゲームを構築しており、さまざまな種類のファイルを読み書きするためのさまざまなクラスがあります。構成ファイル、保存されたゲーム、アセット パッケージなど。アセット パッケージ (モデル、サウンドなど) の例として、ifstream オブジェクトと ofstream オブジェクトをそれぞれ使用する AssetPackReader クラスと AssetPackWriter クラスがあります。現時点では不完全なクラスで、基本的な理論を示しているだけです。

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)

ここで、両方の機能を持つクラスを作成したいと考えています。ができる:

  • 新しいパッケージをゼロから作成する (ライターのように)、
  • 既存のパッケージ (リーダーなど) を開きます。
  • パッケージにアセットを追加します。
    • すべてを最初から書き直さずに(これは遅いです)
    • すべてを最初から書き直します(これにより、ファイルの読み取りが速くなります)

既存のパッケージ化されたデータを変更しないということは、2 つ目の目次が必要になることを意味するため、ユーザーはゼロからの書き換え (FullSave) を好む場合があります (これは、高度な最適化を行わないと、目次間のシークに関してははるかに効率が悪くなります)。

この FullSave を使用すると、ファイルの読み取りが少し速くなりますが (どれだけかかるかはわかりません)、FastSave よりもかなり時間がかかります。特に、変更されている既存のアーカイブがすでにかなり大きい場合はそうです。

そこで、多重継承を使用して、各スーパークラスの読み取り操作と書き込み操作の両方を含むクラスを作成しようとしました。これは、リーダーとライターのクラスの機能をコピーして貼り付けるよりも効率的に思えますが、明らかに何かを理解していません...

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 に置き換えましたが、行き止まりをたどっていることがわかります。

リーダー クラスの 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