gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 00:48:34 24 4
gpt4 key购买 nike

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

Archive.hpp - 用于访问所有内容。如果我能让其他类中的所有函数都无法从外部访问,我会的。 (实际上,我想我可以与 Archive 中的所有其他类成为 friend 并使用私有(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?

  • archive 的 op= 怎么样?

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

我知道我可以放弃当前的 class 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com