zip および rar アーカイブから raw バッファーにファイルを抽出しています。minizip と unrarlib をラップするために以下を作成しました。
Archive.hpp - すべてにアクセスするために使用されます。他のクラスのすべての関数を外部からアクセスできないようにすることができれば、そうします。(実際には、Archive 内の他のすべてのクラスと友達になり、プライベート関数のコールバックを使用できると思いますが、それは遠回りです。)
#include "ArchiveBase.hpp"
#include "ArchiveDerived.hpp"
class Archive {
public:
Archive(string path) {
/* logic here to determine type */
switch(type) {
case RAR:
archive_ = new ArchiveRar(path);
break;
case ZIP:
archive_ = new ArchiveZip(path);
break;
case UNKNOWN_ARCHIVE:
throw;
break;
}
}
Archive(Archive& other) {
archive_ = // how do I copy an abstract class?
}
~Archive() { delete archive_; }
void passThrough(ArchiveBase::Data& data) { archive_->passThrough(data); }
Archive& operator = (Archive& other) {
if (this == &other) return *this;
ArchiveBase* newArchive = // can't instantiate....
delete archive_;
archive_ = newArchive;
return *this;
}
private:
ArchiveBase* archive_;
}
ArchiveBase.hpp
class ArchiveBase {
public:
// Is there any way to put this struct in Archive instead,
// so that outside classes instantiating one could use
// Archive::Data instead of ArchiveBase::Data?
struct Data {
int field;
};
virtual void passThrough(Data& data) = 0;
/* more methods */
}
ArchiveDerived.hpp「派生」は「Zip」または「Rar」
#include "ArchiveBase.hpp"
class ArchiveDerived : public ArchiveBase {
public:
ArchiveDerived(string path);
void passThrough(ArchiveBase::Data& data);
private:
/* fields needed by minizip/unrarlib */
// example zip:
unzFile zipFile_;
// example rar:
RARHANDLE rarFile_;
}
ArchiveDerived.cpp
#include "ArchiveDerived.hpp"
ArchiveDerived::ArchiveDerived(string path) { //implement }
ArchiveDerived::passThrough(ArchiveBase::Data& data) { //implement }
誰かが私ができるようにこのデザインを使用することを提案しました:
Archive archiveFile(pathToZipOrRar);
archiveFile.passThrough(extractParams); // yay polymorphism!
アーカイブの cctor を作成するにはどうすればよいですか?
アーカイブの op= はどうですか?
ArchiveBase::Data
への「名前変更」について何ができArchive::Data
ますか? (minizip と unrarlib の両方が入力と出力にこのような構造体を使用します。データは Zip と Rar では一般的であり、後でそれぞれのライブラリの構造体を作成するために使用されます。) 他のすべては 経由でアクセスされ、外部クラスでArchive
宣言したいと思います。Data
この道も。
class Archive
現在の, nameArchiveBase
を に捨ててArchive
、グローバル ファクトリ関数を使用できることはわかっています。ただし、グローバル関数の使用は避けたかったのです。