c++ - 如何为带有 ptr 的工厂类编写 cctor 和 op= 来抽象成员字段?

标签 c++ abstract-class factory copy-constructor assignment-operator

我正在将 zip 和 rar 存档中的文件提取到原始缓冲区中。我创建了以下内容来包装 minizip 和 unrarlib:

Archive.hpp - 用于访问所有内容。如果我能让其他类中的所有函数都无法从外部访问,我会的。 (实际上,我想我可以将 Archive 中的所有其他类添加为好友并使用私有(private)函数回调...,但这太迂回了。)

#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!
  • 如何为 Archive 编写 cctor?

  • 存档的 op= 怎么样?

  • 如何将 ArchiveBase::Data“重命名”为 Archive::Data? (minizip 和 unrarlib 都使用此类结构进行输入和输出。数据对于 Zip 和 Rar 是通用的,稍后用于创建相应库的结构。)其他所有内容都通过 Archive 访问,我会也喜欢以这种方式在外部类中声明Data

我知道我可以扔掉当前的类Archive,将ArchiveBase命名为Archive,并使用全局工厂函数。但是,我想避免使用全局函数。

最佳答案

首先,您无法“复制”抽象类,因为您无法实例化抽象类。相反,您应该做的是设置该类的 std::tr1::shared_ptr 并传入一个指针。

Archive(ArchiveBase *_archiveBase)

使用 Archive 类之外的工厂函数进行实例化。

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;
}

让智能指针为您操心删除、复制以及所有这些事情。

关于c++ - 如何为带有 ptr 的工厂类编写 cctor 和 op= 来抽象成员字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2535362/

相关文章:

c++ - 不能 dynamic_cast

java - 填充并打印个人 LinkedList 复制品的元素

java - 为什么我需要 FactorySupplier?

PHP 静态工厂方法 : dynamically instantiate instance of the calling class

python-3.x - 如何为抽象类方法构造函数添加类型注释?

javascript - 在工厂函数中公开参数的最佳方法是什么?

c++ - libxml2错误程序c++

c++ - 如何禁用#pragma 警告?

c++ - 类中的 ifstream 变量

c++ - 在析构函数中删除指向 char* vector 的指针(不工作)