举个例子,假设我有一个名为File
的类。现在文件可以以二进制或文本形式打开。我的构造函数当前File(const char*filename)
.假设 open 的实现是完全不同的二进制和文本。我到底该如何构建它?
我想过使用静态函数,但我不想返回指针。我可以传入指针,但我宁愿不允许在没有实际初始化的情况下构造一个类。
我正在考虑在构造函数中使用枚举或布尔值,但这对我来说感觉"错误"(以及我可能这样做的方式(。我可以为二进制和文本使用不同的类名,并且都继承一个基本实现(或其他实现(,即使唯一的区别是构造器。
在C++中这样做的最惯用的方法是什么?
添加标志
enum class open_mode
{
binary,
text
};
File(const char* filename, open_mode mode);
或使用标签
struct binary_tag { };
struct text_tag { };
File(const char* filename, binary_tag);
File(const char* filename, text_tag);
两种惯用方式是工厂函数(没有任何东西强制你返回指针(或标记调度(在标准库中使用,例如在std::variant
中(。
// Factory functions
struct File {
static File openText(char const *filename);
static File openBinary(char const *filename);
};
// Tag dispatching
struct open_as_binary_t {} constexpr open_as_binary;
struct open_as_text_t {} constexpr open_as_text;
struct File {
File(char const *filename, open_as_binary_t);
File(char const *filename, open_as_text_t);
};
我可以为二进制和文本使用不同的类名,并且两者都有 继承基本实现(或其他实现(甚至 虽然唯一的区别是构造器。
是的,一般来说,我可以建议使用多态性。 它始终干净,易于维护,可扩展且易于理解。非常灵活。 创造某些东西的最佳方法可能是工厂设计模式。
例:
class File{ protected: File(); ... }; // make constructor protected!
class BinFile : public File;
class TextFile : public File;
然后你可以用普通的方式使用它:
File *f = new BinFile;
File *f = new TextFile;
将所有常见内容放在类文件中 为每个子类实现任何特定功能。
然后你可以使用一些工厂方法,例如:
File * OpenFile( String pathToFile, "TextFile" );
File * OpenFile( String pathToFile, "BinFile" );
通常,通过这种方式,代码非常灵活。
为什么不更简单:
File(const char *filename,const char *mode)
{
fl=fopen(filename,mode);
//
}
只需拨打myFile = File("log.txt","rt");