我提取的文件从拉rar入原始缓冲区。我创建了以下包装minizip和unrarlib:

存档。hpp -用于访问的一切。如果我可以让所有功能在其他类无法从外,我会的。(实际上,我想我可以朋友的所有其他类归档,并使用专用的功能回...,但是这soo迂回。)

#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 "衍生"正在"拉链"或"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::DataArchive::Data?(两minizip和unrarlib使用这种结构输入和输出。数据是通用的,用于压缩和Rar后来被用于建立各图书馆的结构。) 其他的一切都是通过访问 Archive, 和我想做的声明 Data 在一个外流的这个方式。

我知道我可能会丢掉我的电流 class Archive, ,名称 ArchiveBaseArchive, 和使用全球工厂的功能。然而,我想避免使用全功能。

有帮助吗?

解决方案

首先你不能"复制"一个抽象的类,因为不可能实例之一。而是你应该做的是设立一个性病::tr1::情况的那一类,并通过在一个指针。

Archive(ArchiveBase *_archiveBase)

用一个功能工厂以外的归档类实例。

Archive createArchive(string _path, int _type){
    switch(type) {
    case RAR:
      return Archive( new ArchiveRar(path) );
    case ZIP:
      return Archive( new ArchiveZip(path) );
    case UNKNOWN_ARCHIVE:
      throw exception("Unknown archive format");
      break;
    default:
      throw exception("Improper archive type");
  }

为=操作人员,只要持有到一个聪明的指针,诸如此,使用"="将执行安全转移之间的知识的课程。它执行基准计数和将删除的指针,使你不必只有当它是安全的这样做。

Archive& operator = (Archive& other) {
  m_ArchiveBasePtr = other.m_ArchiveBasePtr;
  return *this;
}

让我们明智的指针担心删除、复制和所有你。

其他提示

麦片 建议工作时,你可以负担得起的浅的副本和一个N-1的关系。它打破了当ArchiveBase子类包含具体的1-on-1数据的每个档案的实例和不分享跨多个对象正常。

一个替代办法全球createArchive()功能就是添加一个抽象的虚拟的克隆()方法ArchiveBase,并然后确定它在每一个亚类(ArchiveZip,ArchiveRar)适当地复制浅或深的副本,作为必要的。

然后你可以叫archive_.克隆()从档案的复制的构造或操作员=如果archive_不是空。(一定要删除(自由)之后!)

我能做些什么有关"重新命名"ArchiveBase::数据档案::数据?(两minizip和unrarlib使用这种结构输入和输出。数据是通用的,用于压缩和Rar后来被用于建立各图书馆的结构。)

有几种选择:

Archive::passThrough() { archive_ -> passThrough( this->getData() ) }
Archive::passThrough() { archive_ -> passThrough( this ) }

或者你可以保持一个落后的参考ArchiveBase到对应的存档目的,其中可查询的数据。

虽然使用小心!它容易得到这种重复的信息的不同步。(你可以获得进入标题文件的循环。) 这就是为什么我喜欢穿的 指针!你总是可以predeclare"类存档",然后使用档案*的指针,而不包括档案。hpp在该标题的文件。(虽然你仍将需要包括存档。hpp。cpp文件。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top