【问题标题】:Design of std::ifstream classstd::ifstream 类的设计
【发布时间】:2011-06-06 03:10:41
【问题描述】:

我们这些已经看到 STL 之美的人尝试尽可能多地使用它,并鼓励其他人在我们看到它们的任何地方使用它,使用 原始指针数组时间>。 Scott Meyers 写了一整本关于 STL 的书,标题为 Effective STL。然而,ifstream 的开发人员发生了什么事,他们更喜欢 char* 而不是 std::string。我想知道为什么ifstream::open() 的第一个参数是const char* 类型,而不是const std::string &。请看一下它的签名:

void open(const char * filename, ios_base::openmode mode = ios_base::in );

为什么会这样?为什么不这样:

void open(const string & filename, ios_base::openmode mode = ios_base::in );

这是设计的严重错误吗?还是这个设计是故意的?可能是什么原因?我看不出他们为什么偏爱char* 而不是std::string。请注意,我们仍然可以将char* 传递给采用std::string 的后一个函数。这不是问题!

顺便说一句,我知道ifstream 是一个typedef,所以不要对我的标题发表评论。:P。它看起来很短,这就是我使用它的原因。

实际的类模板是:

template<class _Elem,class _Traits> class basic_ifstream;

【问题讨论】:

  • 流与 STL 的唯一共同点是两者都是标准库的一部分。 标准库!= STL。

标签: c++ stl class-design std standard-library


【解决方案1】:

因为 IOStream 是在 STL 的一部分集成到标准库之前设计的。字符串类是在那之后制作的。在标准化过程中已经很晚了,修改 IOStream 不被认为是保存。

顺便说一句,作为 C++0X 中微小但方便的更改的一部分,有对这类事情的清理。

【讨论】:

    【解决方案2】:

    My copy of the standard 不同意你的观点。它说这两个都是重载:

    void open(const char* s, ios_base::openmode mode = ios_base::in);
    void open(const string& s, ios_base::openmode mode = ios_base::in);
    

    但是,该标准的副本是该标准的下一版本 C++0x 的草案。

    这样做的原因是 iostreams 库早于 std::basic_string,并且因为库设计者不希望有人必须使用 #include &lt;string&gt; 以及所有其他相关的包袱,如果他们不想使用它.

    【讨论】:

    • 您可能正在查看 C++0X 草案。
    • @AProgrammer:嗯.. 不知道那已经改变了。添加了指向我正在使用的副本的链接,以使其更清晰。
    • @Billy ONeal:那不是 C++03。我说的是 C++03。
    • @Billy :就像 C++0x 有一个采用 std::string 的版本一样,C++03 也可以做同样的事情。没有?
    • @Nawaz:是的,他们本可以。他们也可以将整个标准库放入#include &lt;whole_standard_library&gt;,但他们没有。
    【解决方案3】:

    std::string 获取 C 字符串通常不会比从 C 字符串构造 std::string 更昂贵,因此,鉴于您可能希望将 std::ifstream 与来自的文件名一起使用两者,在界面中使用const char* 的成本并不高。

    这是一个严重的设计错误吗?

    你不能用当前界面做什么?使用const std::string&amp; 在接口产量方面有什么具体和显着的好处?

    在我看来,std::string 重载的真正好处是帮助初学者在第一次尝试一起使用 std::string 和流时轻松搞定。对于经验丰富的 C++ 开发人员而言,与开发代码的其他工作相比,必要时编写 .c_str() 的微不足道的成本可能可以忽略不计。

    【讨论】:

    • @Charles Bailey:这看起来像是事后合理化。 :P
    • @Nawaz:如果不是事后合理化,你要求什么(鉴于当前接口已经标准化)?
    • @Charles Bailey:我的意思是,如果他们更喜欢std::string 而不是char*,你也会说同样的话。只是以相反的顺序。它仍然看起来很有道理。:|...而我的问题是,如果没有任何危害,他们自己为什么不使用 std::string 。
    • @bdonlan: 是的,但是file.open("my very long file name path.txt") 调用涉及堆分配的 std::string 构造。
    • 换句话说,如果我现在正在设计一个接口,其中需要一个字符串作为输入(不是任意的char 数据),并且该字符串可能来自字符串文字,静态分配或动态输入,我通常会选择 const char* 而不是 const std::string&amp; 并且不会为过载而烦恼。我不认为在界面中有const char* 是不好的设计,我相信它比需要std::string 稍微灵活一点,就像使用const shared_ptr&lt;X&gt;&amp; 不如const X&amp; 灵活;它不会强制使用特定的存储策略。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2010-09-26
    • 2010-11-08
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    相关资源
    最近更新 更多