为什么C++11的字符串新函数(stod,stof)不是字符串类的成员函数?

7
为什么C++11中<string>头文件的新函数(stod, stof, stoull)不是string类的成员函数?
难道写mystring.stod(...)而不是stod(mystring,...)不符合更多的C++规范吗?

8
他们不需要这样做,而且std::string已经有太多成员函数了。请参见单体结构"解绑"的 GOTW - juanchopanza
2
如果stod是一个可以接受任何Sequence对象而不仅仅是std::string的模板,那就太好了。 - Siler
1
std::string已经是一个庞大的类,不需要更多的成员函数。 - The Forest And The Trees
有一个标准委员会在决定这个问题,所以要求“更符合C++标准”的话应该引起警惕,因为这里的观点可能不是最好的。 - PlasmaHH
3个回答

22

许多人感到惊讶,但是C++ 不是 面向对象的语言(与Java或C#不同)。

C++是一种多范式语言,因此尽可能使用最好的工具来完成任务。在这种情况下,自由函数 是正确的工具。

指导原则: 优先选择非成员函数而不是成员函数(来自Efficient C++,第23条)

原因: 成员函数或友元函数可以访问类内部,而非成员函数不能; 因此,使用非成员函数可以增加封装性

例外: 当成员函数或友元函数提供显着优势时(例如性能),尽管存在额外的耦合,但仍值得考虑。例如,即使std::find运行良好,但关联容器(例如std::set)提供了一个成员函数std::set::find,它以O(log N)的速度工作,而不是O(N)。


3
如果那个准则能够稍早一点应用于std::basic_string的话... - pmr
@pmr:是的,std::basic_string和所有IO流都是存在于标准化之前的恐龙;实际上,最初版本的string完全是基于索引定义的,在标准化过程中添加了所有迭代器重载以使其成为一个序列...但是为了兼容性,前面的方法被保留了。 - Matthieu M.
如果全局的非成员非友元函数的工作依赖于类的私有数据成员,该怎么办? - David G
@0x499602D2:这是不可能的构造,因为非成员非友元函数的原则就是只能访问“public”接口。 - Matthieu M.
@MatthieuM。这是在暗示我们应该实现getter和setter吗? - David G
4
抱歉,我不太明白你的推理思路。我从未提到过getter和setter......如果你想实现一个需要绝对访问类内部的方法,那显然它将作为成员函数或友元函数实现;这里没有争议。该指南适用于"当你有选择时",而且往往你是有选择的,你只需要退后一步意识到它。如果没有选择,那就没有选择了。 - Matthieu M.

3
根本原因是它们与字符串无关,不应在那里。停下来想一想,用户定义的类型应该遵循与内置类型相同的规则,因此每次定义新的用户类型时,都必须向std::string添加一个函数。这实际上在C++中是可能的:如果std::string有一个成员函数模板to(没有通用实现),则可以为每个类型添加专门化,并调用str.to()或str.to()。但这真的是您想要的吗?这对我来说似乎不是一个干净的解决方案,每个人都必须编写一个新类并向std::string添加一个专门化。将这些东西放入字符串类会败坏它,并且实际上是面向对象试图实现的相反情况。
如果您坚持纯面向对象,它们必须是double、int等的成员变量。 (实际上是构造函数。这就是例如Python所做的。)C ++不坚持纯面向对象,也不允许基本类型如double和int有成员或特殊构造函数。因此,免费函数既是可接受的解决方案,也是在语言环境中唯一的干净解决方案。
FWIW:转换为/从文本表示始终是一个棘手的问题:如果我在目标类型中进行转换,则我引入了对目标类型中的各种文本源和接收器的依赖-这些可能会随时间变化。如果我在源或接收器类型中执行它,则使它们依赖于要转换的类型,这甚至更糟。 C ++的解决方案是定义一个协议(在std::streambuf中),用户编写新的自由函数(operator<<和operator>>)来处理转换,并依赖于运算符重载决定正确的函数。自由函数解决方案的优点是转换既不属于数据类型(因此无需了解来源和接收器),也不属于源或接收器类型(因此无需了解用户定义的数据类型)。这对我来说似乎是最好的解决方案。像stod这样的函数只是方便函数,使特别频繁的使用更容易编写。

1
实际上,它们是一些实用函数,不需要在主类中。类似的实用函数,如atoi、atof,在stdlib.h中定义(但是针对char*),它们也是独立的函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接