gpt4 book ai didi

c++ - 避免 dynamic_cast 的替代设计?

转载 作者:太空狗 更新时间:2023-10-29 21:18:05 27 4
gpt4 key购买 nike

假设我有 Archive接口(interface)和File界面。

  • 每个File保证至少有 std::string name .
  • 每个Archive可以std::vector<File*> Archive::list() const它的文件。
  • 每个Archive可以Archive::extract(std::vector<File*> files) .

然后我有ZipArchiveZipFile , ZipFile包含存档文件中的偏移量和其他实现细节。然后是TarArchive/TarFile等等。这些填充中的每一个 std::vector<File*> list() constZipFile 的实例, TarFile

list()旨在让用户有机会选择要解压的文件。他们从该 vector 中选择元素,然后将此 vector 传递给 extract() .

此时,ZipArchive需要假设它传递了正确的类型并执行 dynamic_cast<ZipFile*>(file)访问实现细节。

这感觉很糟糕。这是可以接受的吗?有其他选择吗?

最佳答案

如评论中所建议,您可以将提取界面从Archive 中移出。至 File .存档将返回 std::vector<File*> ,但实际上每个对象都是,例如 ZipFile , 并且会知道它属于哪个存档以及它的类型是什么,并且能够调用适当的提取方法。

因此,您可以在不检查存档类型的情况下获得代码:

struct File;
struct Archive {
virtual std::vector<File*> fileList() = 0;
};

struct File {
File(std::string name_) : name(name_) {}
virtual void extract() = 0;
std::string name;
};

struct ZipFile;
struct ZipArchive: public Archive {
void extractFile(ZipFile& file);
virtual std::vector<File*> fileList();
};

struct ZipFile: public File {
ZipArchive* archive;
virtual void extract() { archive->extractFile(*this); }
ZipFile(std::string name_, ZipArchive* archive_) : File(name_), archive(archive_) {}
};

完整示例:http://ideone.com/kAs5Jc

如果你想通过一次调用提取多个文件会更困难,但你可以有存档的 extractFile只记得那个文件,然后是 Archive 中的一个特殊方法。类一次提取所有记住的文件。我认为这甚至可以隐藏在一个相当简单的界面下。

关于c++ - 避免 dynamic_cast 的替代设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30933943/

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