我想添加一个新的成员函数" charReplace"到字符串类。该函数将用一个字符替换一个字符的所有出现。所以我准备了一个示例代码。
#include <iostream>
#include <string>
std::string string::charReplace(char c1, char c2) { //error in this line
while(this->find(c1) != std::string::npos) {
int c1pos = this->find(c1); //find the position of c1
this->replace(c1pos, 1, c2); //replace c1 with c2
}
return *this;
}
int main() {
std::string s = "sample string";
s.charReplace('s', 'm') /* replace all s with m */
std::cout << s << std::endl;
}
但它不起作用。编译时我在第4行收到以下错误。
错误:&#39;字符串&#39;没有命名类型
我知道通过创建非成员函数可以很容易地获得相同的结果。但我想用成员函数来做。那么,有没有办法在c ++中做到这一点?
P.S。我还是c ++的新手。我一直在使用它几个月。所以,请尽量让你的答案易于理解。
答案 0 :(得分:7)
您的选择是:
答案 1 :(得分:2)
您无法添加到std::string
界面,但可以执行此操作:
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
std::string s = "sample string";
std::replace(s.begin(), s.end(), 's', 'm'); /* replace all s with m */
std::cout << s << std::endl;
}
<强>输出:强>
mample mtring
答案 2 :(得分:1)
错误消息指向此标识符
std::string string::charReplace(char c1, char c2) {
^^^^^^
编译器不知道。编译器只知道std::string
,但它不知道非限定标识符string
的含义。
但无论如何这种方法都是错误的,因为类的所有成员都应该在类定义中声明。您可能不会在不更改其定义的情况下添加类的新成员。
您可以编写一个非成员函数来执行相同的任务。
考虑到您的函数实现存在严重错误。如果参数c1
和c2
指定相同的字符,那么该函数将具有无限循环。
我会按照以下方式编写函数
std::string & charReplace( std::string &s, char c1, char c2 )
{
for ( std::string::size_type pos = 0;
( pos = s.find( c1, pos ) ) != std::string::npos;
++pos )
{
s[pos] = c2;
}
return s;
}
答案 3 :(得分:0)
您不能(也不应该)更改std::string
类(特别是因为它在C ++ 11中标准化并由其标准库提供)。
你可以继承std::string
(但这经常是皱眉头)。
答案 4 :(得分:0)
您不能将函数“添加”到已定义的类中。
你可以做的是做一个独立的功能,叫做charReplace
答案 5 :(得分:0)
除非你直接修改它们的定义(你不应该使用标准类),否则无法在C ++中为现有类添加方法。
因此,您只能选择两个选项:
std::string charReplace(std::string& str, char c1, char c2){...};
,称为charReplace(s,c1,c2)
。这是唯一可行的选择。答案 6 :(得分:0)
但我想用成员函数来做。那么,还有办法吗? 这在c ++?
没有
然而,真正的问题应该是:为什么?
std::string
已经足够臃肿了。 Herb Sutter曾经写过一篇关于它的GotW article。
在C ++中,通过独立的非友好函数扩展类的功能是一种非常好的做法。这极大地增强了封装,因为独立的非朋友功能无法访问private
或protected
成员。
如果你看一下标准库或Boost库,你会发现这个原理已经应用了很多。标准库的整个“STL”(=容器/算法/迭代器)部分基于它。容器类(如std::set
或std::vector
)的公共接口不包含reverse
,count_if
或all_of
等函数。有独立的功能:
你应该在C ++中遵循这个优秀的例子,而不是反对它。
从技术上 可以从std::string
派生并将成员函数添加到派生类。但这是不良做法。这是一个很好的问题,对这个主题有很好的答案,包括对Scott Meyers或Andrei Alexandrescu等着名专家的书籍的参考:
Why should one not derive from c++ std string class?
最后,请注意,这种考虑并非C ++独有。以Java为例。在Java中,最佳做法是从设计为基类的类派生 only 。这甚至是Joshua Bloch着名的“Effective Java”一书中的一个项目。对于Java的String
类,当然,你甚至无法从它派生,因为它是final
。有可能如果C ++标准库是今天设计的,在C ++ 11中添加了新功能,std::string
也将是final
(尽管C ++的发明者Bjarne Stroustrup显然已经从来没有成为最后阶级的忠实粉丝,但这是另一个故事。)