C++ 扩展c++;字符串成员函数

C++ 扩展c++;字符串成员函数,c++,string,C++,String,我需要执行一个不区分大小写的查找,并找到了下面的代码 bool ci_equal(char ch1, char ch2) { return toupper((unsigned char)ch1) == toupper((unsigned char)ch2); } size_t ci_find(const string& str1, const string& str2) { string::const_iterator pos = std::search(str

我需要执行一个不区分大小写的查找,并找到了下面的代码

bool ci_equal(char ch1, char ch2)
{
    return toupper((unsigned char)ch1) == toupper((unsigned char)ch2);
}

size_t ci_find(const string& str1, const string& str2)
{
    string::const_iterator pos = std::search(str1. begin ( ), str1. end ( ), str2.
    begin ( ), str2. end ( ), ci_equal);
    if (pos == str1. end ( ))
        return string::npos;
    else
        return pos - str1. begin ( );
}
这让我想知道如何才能使它成为“string”的成员函数,从而可以这样调用它:

string S="abcdefghijklmnopqrstuv";
string F="GHI";

S.ci_find(F);
我意识到非英语语言中的大小写转换有很多问题,但这不是我感兴趣的问题

作为新手,我很快就迷失在容器和模板中


有什么办法可以这样做吗?有人能给我举个类似的例子吗?

std::string
不是用来扩展的


你可以把一个STD::string封装到你的一个类中,并在那个类中设置那些成员函数。

< P>我认为大多数有经验的C++程序员都会同意这是个坏主意。如果有什么不同的话,
std::string
已经有太多的成员函数,添加更多的成员函数会使情况变得更糟。更糟糕的是,如果要这样做,您可能会通过继承来实现——但是
std::string
并不是设计用来作为基类的,将其作为一个基类使用会导致代码脆弱且容易出错


对于如何做的另一个想法,你可能想阅读。不过,一定要阅读整篇文章,了解如何做,以及为什么你可能不想做。最终,您现在拥有的可能是最好的选择——将不区分大小写的搜索与
std::string
本身分开。

可能以标准库算法
为例

大多数情况下,定义一个。更具体地说,是一个。这样做的好处是,函子以及未修改的
字符串
类可以存储在STL容器中,STL将使用自定义函子进行操作

它是一个具有默认构造函数和重载的布尔运算符()的类(const string&x,const string&y)

它执行不区分大小写的比较

还可以根据需要定义相等函子


<>真的,如果你特别问“C++是否有C方法这样的扩展方法”,那么就不可能使用<代码>=< />代码> <代码>,那么具体的答案是“否”。除了对实现进行黑客攻击之外,没有办法将成员函数添加到实际的
std::string
类中。这可能不像听起来那么难,但这是一个听起来那么糟糕的主意。哦,还有“有人能给我举个类似的例子吗?”-你已经写的代码是C++风格的。类是通过提供非成员函数来对其进行扩展或增强的,C++程序员并不是非常热衷于<代码> .< /COD>成员函数调用语法,他们认为这是一个问题;我要感谢所有回答这个问题的人。简短的回答似乎是“不,不可能在字符串中添加其他成员函数”。因为这是我问题的核心,所以我决定接受Tom的回答。是的,尽管正如他对
ci\u find
的实现所显示的,如果他将此作为一种算法提供,它将只是使用特定谓词的
std::search
的一个轻微变体。同意
std::basic_string
不是设计为从中继承的,因为它没有虚拟析构函数,因此是对扩展类实例的多态删除(称之为stringex
)使用
basic\u string
指针会泄漏,因为
stringex
的析构函数没有被调用。但是如果
stringex
不需要,甚至没有定义析构函数,因为这个类包含的都是本机类型和附加成员函数,没有内存分配,那么会发生什么问题呢?@Praetorian:它仍然是未定义的行为,而且它仍然是不必要的,因为实现同样的行为(同时更好地保留封装)的惯用方法是定义非成员函数。@jalf:它有什么未定义的?(我不是在和你争论,只是想理解)在我描述的场景中,唯一需要调用的析构函数是
basic\u string
,当使用
basic\u string
指针删除
stringex
对象时,应该调用该析构函数,而不管后者是否具有
虚拟
析构函数re未定义
stringex
的析构函数是否将调用
basic_string
的析构函数?@Praetorian:这是未定义的,因为传递给
运算符delete
的指针与
运算符new
返回的指针不同,除非您拥有虚拟析构函数或删除最派生的对象。注意在替换
char\u traits
时,参数将区分大小写的行为替换为不区分大小写的行为。要对
ci\u字符串执行区分大小写的
find
,需要一个自由函数…整圈。因此,我使用()运算符的定义定义了一个类qqq,声明一个实例ci\u find,然后调用ci\u find(s1,s2)。为什么这比像我一样简单地定义ci_find要好呢?我想我可以将compare函数封装在类中。或者你是说它可以成为string或basic_string的一部分?@Mike:我很抱歉因为我没有仔细阅读这个问题而给出了错误的答案。事实上,你的问题是一个非常有趣的oNE,并要求更详细的答复。我将放弃我的第一个答案,并写第二个。(对不起,这需要很长时间。)谢谢。迈克:(1)如果你的平台或C++库提供了一个不区分大小写的子串搜索,使用它。它可能被命名为“代码> StrutRe/Cube >,<代码> WCSISTR < /代码>等(2)。如果你要写自己的,确保你理解Knuth Morris Pratt和Boyer Moore算法。(3)还要确保你理解
char\u特性