如何在c ++中的内置类中添加成员函数?

时间:2015-08-06 08:47:22

标签: c++ string member-functions

我想添加一个新的成员函数" 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 ++的新手。我一直在使用它几个月。所以,请尽量让你的答案易于理解。

7 个答案:

答案 0 :(得分:7)

你不能。这是C ++,而不是JavaScript(你可以在任何类中创建原型)。

您的选择是:

  1. 继承
  2. 组合物
  3. 自由职能

答案 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的含义。

但无论如何这种方法都是错误的,因为类的所有成员都应该在类定义中声明。您可能不会在不更改其定义的情况下添加类的新成员。

您可以编写一个非成员函数来执行相同的任务。

考虑到您的函数实现存在严重错误。如果参数c1c2指定相同的字符,那么该函数将具有无限循环。

我会按照以下方式编写函数

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 ++中为现有类添加方法。

因此,您只能选择两个选项:

  • 子类:除非您知道自己在做什么,否则不鼓励使用标准库类。 (如果你不得不问,你可能不会。在这里,E.G。虚拟析构函数是一个重点。)
  • 添加自由函数(或静态类函数):在您的情况下,这将是std::string charReplace(std::string& str, char c1, char c2){...};,称为charReplace(s,c1,c2)。这是唯一可行的选择。

答案 6 :(得分:0)

  

但我想用成员函数来做。那么,还有办法吗?   这在c ++?

没有

然而,真正的问题应该是:为什么?

std::string已经足够臃肿了。 Herb Sutter曾经写过一篇关于它的GotW article

在C ++中,通过独立的非友好函数扩展类的功能是一种非常好的做法。这极大地增强了封装,因为独立的非朋友功能无法访问privateprotected成员。

如果你看一下标准库或Boost库,你会发现这个原理已经应用了很多。标准库的整个“STL”(=容器/算法/迭代器)部分基于它。容器类(如std::setstd::vector)的公共接口不包含reversecount_ifall_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显然已经从来没有成为最后阶级的忠实粉丝,但这是另一个故事。)