为什么标题<string>
(stod
,stof
,stoull
)的那些C ++ 11新函数不是string
类的成员函数?
写mystring.stod(...)
而不是stod(mystring,...)
而不是更符合C ++?
答案 0 :(得分:22)
许多人都感到惊讶,但C ++ 不是面向对象的语言(与Java或C#不同)。
C ++是一种多范式语言,因此尽可能尝试使用最佳工具。在这种情况下,自由功能是正确的工具。
指南:将非会员非好友功能推荐给会员功能(来自Efficient C ++,第23项)
原因:成员函数或朋友函数可以访问类内部,而非成员非朋友函数则不能;因此,使用非成员非朋友函数会增加封装。
例外:当成员函数或朋友函数提供显着优势(例如性能)时,尽管有额外的耦合,但值得考虑。例如,即使std::find
工作得很好,关联容器(如std::set
)也提供了一个成员函数std::set::find
,它在O(log N)而不是O(N)中工作。
答案 1 :(得分:3)
根本原因是他们不属于那里。他们
与字符串没有任何关系。停下来想一想
关于它。用户定义的类型应遵循相同的规则
内置类型,因此每次定义新用户类型时,
你必须向std::string
添加一个函数。这个会
实际上可以在C ++中使用:如果std::string
有一个成员
函数模板to
,没有通用的实现,你
可以为每种类型添加专门化,并调用
str.to<double>()
或str.to<MyType>()
。但这真的
你想要什么。它对我来说似乎不是一个干净的解决方案,
让每个人都写一个新课程必须添加
std::string
的专业化。把这些东西
在字符串类中将它标准化,并且实际上正好相反
OO试图实现的目标。
如果你坚持使用纯粹的OO,他们就必须这样做
double
,int
等的成员(构造函数,真的。这个
正如Python所做的那样。)C ++并不坚持纯粹
OO,并且不允许double
和int
等基本类型
有成员或特殊建设者。所以自由功能是
既可接受的解决方案,也是唯一的清洁解决方案
可能在语言的背景下。
FWIW:始终是文本表示的转换
一个微妙的问题:如果我在目标类型中这样做,那么我就是
引入了对文本的各种来源和汇的依赖
在目标类型---这些可以随时间变化。如果我这样做的话
源或接收器类型,我使它们依赖于类型
被转换,这更糟糕。 C ++解决方案是
定义用户写入的协议(在std::streambuf
中)
一个新的自由函数(operator<<
和operator>>
)来处理
转换,并依赖于运算符重载决策
找到正确的功能。免费功能的优点
解决方案是转换既不是数据的一部分
类型(因此不必知道源和汇)也没有
源或接收器类型(因此不必知道
用户定义的数据类型)。这似乎是最好的解决方案
我。像stod
这样的函数只是便利函数,
这使得一个特别频繁的使用更容易写。
答案 2 :(得分:1)
实际上它们是一些实用功能,它们不需要在主类中。在stdlib.h中定义了类似的实用程序函数,如atoi,atof(但对于char *),它们也是独立的函数。