What's the most idotomatic way of declaring two constructors with the same args?

て烟熏妆下的殇ゞ 提交于 2020-06-16 16:59:13

问题


As an example lets say I have a class called File. Now file can be opened as binary or text. My constructor is currently File(const char*filename). Let's suppose the implementation of open is completely different binary and text. How the heck do I construct this?

I thought about using a static function but I don't want to return a pointer. I could pass in a pointer but I rather not allow a class be constructed without actually initializing it.

I was thinking about having an enum or bool in the constructor but it feels 'wrong' to me (and the way I may do this). I could have a different class name for binary and text and have both inherit a base implementation (or the other implementation) even though the only difference is the constuctor.

What's the most idiomatic way of doing this in C++?


回答1:


Two idiomatic ways are a factory function (nothing forces you to return a pointer), or tag dispatching (which is used in the standard library, for example in 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);
};



回答2:


Add a flag

enum class open_mode
{
    binary,
    text
};

File(const char* filename, open_mode mode);

or use a tag

struct binary_tag { };
struct text_tag { };
File(const char* filename, binary_tag);
File(const char* filename, text_tag);



回答3:


I could have a different class name for binary and text and have both inherit a base implementation (or the other implementation) even though the only difference is the constuctor.

Yes, in general, I can propose to use the polymorphism. It is always clean, easy maintainable, extensible and understandable. Very flexible. The best for creating something could be the factory design pattern.

Example:

class File{ protected: File(); ... }; // make constructor protected!
class BinFile : public File;
class TextFile : public File;

Then you could use it in the ordinary way:

File *f = new BinFile;
File *f = new TextFile;

Place all common stuff in class File Implement any specific functionality per child class.

Then you could engage some factory method like:

File * OpenFile( String pathToFile, "TextFile" );
File * OpenFile( String pathToFile, "BinFile" );

In general, in this way, the code is very flexible.




回答4:


Why not even simpler:

File(const char *filename,const char *mode)
{
    fl=fopen(filename,mode);
    // 
}

And simply call with myFile = File("log.txt","rt");



来源:https://stackoverflow.com/questions/61887903/whats-the-most-idotomatic-way-of-declaring-two-constructors-with-the-same-args

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!