为什么 (i|o)fstream 采用 const char* 参数作为文件名?
为什么 std::(i|o)fstream 类的构造函数和 open 方法采用 const char* 形式的文件名作为参数而不是 std::string
?看起来 STL 的创建者希望使用他们编写的内容,而不是使用他们编写的类来替换的类型。
Why does the constructor and open
method of the std::(i|o)fstream classes take the name of a file as a parameter in the form of a const char*
instead of an std::string
? It seems like the creators of the STL would want to use what they had written instead of using the type they wrote a class to replace.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
该库的
string
部分是在流之后开发的,没有人想到进行明显的修改。只是出于政治和时间现实,他们在发布 C++98 之前从未抽出时间解决这个问题,并且没有人费心再次提起它,因为您总是可以使用
.c_str()
解决它。C++0x 修复了这个问题(参见 27.9.1.6)。
欢迎来到 C++。
The
string
part of the library was developed after streams, and nobody thought to make the obvious modifications.It's merely out of political and temporal reality that they never got around to this before shipping C++98, and nobody bothered bringing it up again because you could always solve it with
.c_str()
.C++0x fixes this (see 27.9.1.6).
Welcome to C++.
据我所知,这主要是出于历史原因。
ifstream
和ofstream
早在std::string
之前就已存在。那时他们甚至没有std::
。It's mainly for historical reasons, as far as I know.
ifstream
andofstream
existed long beforestd::string
. They didn't even have astd::
back then.std::string
类实现了“运行时大小可调整大小的字符串”的概念。这是应该使用此类的时候 - 当您需要一个其大小仅在运行时已知并且也可以在运行时调整大小的字符串时。在不需要这些功能的情况下,使用 std::string 就显得有些过分了。显然,该库的作者并不认为他们需要一个运行时可调整大小的字符串来表示文件名,因此他们选择了一个简约的解决方案:他们使用 C 字符串,其中 C 字符串就足够了。这实际上是设计库接口的一个非常好的原则:永远不要需要你并不真正需要的东西。确实,现在我们经常看到有人鼓励 C++ 程序员在需要字符串时使用
std::string
,任何字符串。他们经常声称经典的 C 字符串应该保留给 C 代码。一般来说,这是一种虚假的哲学。无端使用像 std::string 这样的相对较重的对象在 Java 等语言中更合适,但在 C++ 中通常是不可接受的。是的,在某些 C++ 应用程序中始终使用
std::string
是可能的(“可以用 C++ 编写 Java 程序”),但是在这样一个通用的低端应用程序中, level 库作为 C++ 标准库,在没有充分理由(即强加不必要的要求)的情况下强迫用户使用 std::string 看起来不太好。Class
std::string
implements the concept of "run-time-sized resizable string". This is when this class should be used - when you need a string whose size is only known at run-time and which is run-time resizable as well. In situations when you don't need these features usingstd::string
is an overkill. Apparently, the authors of the library didn't think that they needed a run-time resizable string to represent a file name, so they opted for a minimalistic solution: they used a C-string where a C-string was sufficient. This is actually a very good principle for designing library interfaces: never require something that you don't really need.It is true that these days we often see people who encourage C++ programmers to use
std::string
whenever they need a string, any string. They often claim that classic C strings should be reserved to C code. In general case this is a bogus philosophy. Gratuitous use of comparatively heavy objects likestd::string
is more appropriate in languages like Java, but is normally unacceptable in C++.Yes, it is possible to get away with using
std::string
all the time in some C++ applications ("it is possible to write a Java program in C++"), but in such a generic low-level library as C++ standard library forcing the user to usestd::string
without a good reason (i.e. imposing unnecessary requirements) would not look good.我敢打赌,
iostream
层次结构/库(包括(i|o)fstream
)是与std::string
分开发明/开发的,他们只是在std
库中组合在一起时才第一次见面。在发明 iostream 时,可能有许多不同的 string 实现,为了支持最大的可移植性,他们决定押注于始终可用的数据类型,并且这是一个简单的
char const*
c 风格字符串。My bet is that the
iostream
hierarchy / library (including(i|o)fstream
) was invented / developed apart fromstd::string
, and they only first met when put together in thestd
library.At the time of invention of
iostream
, there were maybe many differentstring
implementations going around and to support maximum portability, they decided to bet on a data type that's always available, and that's a simplechar const*
c-style string.只需查看 G++ 的
标头,我注意到对std::basic_string
或其任何typedef
的所有引用都是在用#ifdef __GXX_EXPERIMENTAL_CXX0X__
分隔的部分中。这对我来说表明 iostreams 库被设计为独立于字符串库,因此,如果您不使用 std::string ,则无需为其付费(这有历史上是 C++ 中非常重要的设计原则)。这也可以解释为什么
getline(std::istream&, std::string&)
是
中定义的自由函数,而不是像这样的成员函数istream::getline(char*,streamsize)
。这也表明我在 C++0x 标准化中将此视为设计缺陷,并认为使 iostreams 库独立于字符串库带来的不便是不值得的。
(我懒得去找 C++0x 规范的工作草案,或者系统地检查所有 iostreams 相关的标头来确认其中的任何一个。)
Just looking through my G++'s
<fstream>
header, I noticed that all of the references tostd::basic_string
or any of itstypedefs
are in sections delimited with#ifdef __GXX_EXPERIMENTAL_CXX0X__
.This suggests to me that the iostreams library was designed to be independent of the string library, so that if you didn't use
std::string
, you didn't have to pay for it (this has historically been a very important design principle in C++). This would also explain whygetline(std::istream&, std::string&)
is a free function defined in<string>
, rather than a member function likeistream::getline(char*, streamsize)
.This also suggests to me in the C++0x standardization viewed this as a design flaw, and decided that the inconvenience of making the iostreams library independent of the string library just wasn't worth it.
(I can't be bothered to go find a working draft of the C++0x spec, or systematically check all of the iostreams related headers to confirm any of this.)