如何在 C++ 的内置 类 中添加成员函数?
How can I add member functions in built-in classes in c++?
我想给字符串class添加一个新的成员函数"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 行收到以下错误。
error: 'string' does not name a type
我知道通过创建非成员函数很容易得到相同的结果。但我想使用成员函数来完成。那么,有没有办法在 C++ 中做到这一点?
P.S。我还是 c++ 的新手。我只使用了几个月。所以,请尽量让你的回答通俗易懂。
您不能(也不应该)更改 std::string
class(特别是因为它已在 C++11 中标准化并由其标准库提供)。
你可以subclass std::string
(但这通常不受欢迎)。
你不能。这是 C++,而不是 JavaScript(您可以在其中制作任何 类 的原型)。
您的选择是:
- 继承
- 作文
- 独立函数
您不能 "add" 已定义的函数 class。
你可以做一个独立的函数,叫做 charReplace
无法在 C++ 中向现有 classes 添加方法,除非您直接修改它们的定义(您不应该对标准 classes 执行此操作)。
因此,您只有两种选择:
- Subclassing:标准库 classes 不鼓励这样做,除非你知道自己在做什么。 (如果你不得不问,你可能不是。例如,虚拟析构函数在这里很重要。)
- 添加自由函数(或静态 class 函数):在您的情况下,这将是
std::string charReplace(std::string& str, char c1, char c2){...};
,称为 charReplace(s,c1,c2)
。这是这里唯一可行的选择。
错误信息指向这个标识符
std::string string::charReplace(char c1, char c2) {
^^^^^^
编译器不知道。编译器只知道 std::string
但不知道非限定标识符 string
是什么意思。
但无论如何这种方法都是不正确的,因为 class 的所有成员都应在 class 定义中声明。在不更改其定义的情况下,您不得添加 class 的新成员。
您可以编写一个非成员函数来完成相同的任务。
考虑到您的函数实现存在严重错误。如果参数 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;
}
您无法添加到 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
But I want to do it using a member function. So, is there a way to do
this in c++?
没有
然而,真正的问题应该是:为什么?
std::string
已经够臃肿了。以至于 Herb Sutter 曾经写过一篇关于它的 GotW article。
在 C++ 中,通过独立的非友元函数扩展 class 的功能是一个很好的做法。这极大地 增强了封装性 ,因为独立的非友元函数无法访问 private
或 protected
成员。
如果你看一下标准库或者Boost库,你会发现这个原则应用的很多。标准库的整个 "STL" (= containers/algorithms/iterators) 部分都是基于它的。像std::set
或std::vector
这样的容器class的public接口并不像reverse
、count_if
或all_of
那样具有完整的功能.有独立的功能:
- http://en.cppreference.com/w/cpp/algorithm/reverse
- http://en.cppreference.com/w/cpp/algorithm/count
- http://en.cppreference.com/w/cpp/algorithm/all_any_none_of
- 等...
你应该在 C++ 中遵循这个优秀的例子,而不是反对它。
技术上 可以从 std::string
派生并向派生的 class 添加成员函数。但这是不好的做法。这是一个很好的问题,在这个主题上有很好的答案,包括对 Scott Meyers 或 Andrei Alexandrescu 等知名专家书籍的引用:
Why should one not derive from c++ std string class?
最后请注意,这种考虑并不是C++独有的。以Java为例。在 Java 中,最好的做法是从 classes 中派生出 only,这些 classes 被设计为基础 classes。这甚至是 Joshua Bloch 著名的 "Effective Java" 书中的一个项目。在 Java 的 String
class 的情况下,你甚至无法从中推导出来,当然,因为它是 final
。很有可能,如果 C++ 标准库是今天设计的,随着 C++11 中添加的新功能,std::string
也将是 final
(尽管 C++ 的发明者 Bjarne Stroustrup 显然已经从来都不是 final classes 的忠实粉丝,但这是另一回事了)。
我想给字符串class添加一个新的成员函数"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 行收到以下错误。
error: 'string' does not name a type
我知道通过创建非成员函数很容易得到相同的结果。但我想使用成员函数来完成。那么,有没有办法在 C++ 中做到这一点?
P.S。我还是 c++ 的新手。我只使用了几个月。所以,请尽量让你的回答通俗易懂。
您不能(也不应该)更改 std::string
class(特别是因为它已在 C++11 中标准化并由其标准库提供)。
你可以subclass std::string
(但这通常不受欢迎)。
你不能。这是 C++,而不是 JavaScript(您可以在其中制作任何 类 的原型)。
您的选择是:
- 继承
- 作文
- 独立函数
您不能 "add" 已定义的函数 class。
你可以做一个独立的函数,叫做 charReplace
无法在 C++ 中向现有 classes 添加方法,除非您直接修改它们的定义(您不应该对标准 classes 执行此操作)。
因此,您只有两种选择:
- Subclassing:标准库 classes 不鼓励这样做,除非你知道自己在做什么。 (如果你不得不问,你可能不是。例如,虚拟析构函数在这里很重要。)
- 添加自由函数(或静态 class 函数):在您的情况下,这将是
std::string charReplace(std::string& str, char c1, char c2){...};
,称为charReplace(s,c1,c2)
。这是这里唯一可行的选择。
错误信息指向这个标识符
std::string string::charReplace(char c1, char c2) {
^^^^^^
编译器不知道。编译器只知道 std::string
但不知道非限定标识符 string
是什么意思。
但无论如何这种方法都是不正确的,因为 class 的所有成员都应在 class 定义中声明。在不更改其定义的情况下,您不得添加 class 的新成员。
您可以编写一个非成员函数来完成相同的任务。
考虑到您的函数实现存在严重错误。如果参数 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;
}
您无法添加到 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
But I want to do it using a member function. So, is there a way to do this in c++?
没有
然而,真正的问题应该是:为什么?
std::string
已经够臃肿了。以至于 Herb Sutter 曾经写过一篇关于它的 GotW article。
在 C++ 中,通过独立的非友元函数扩展 class 的功能是一个很好的做法。这极大地 增强了封装性 ,因为独立的非友元函数无法访问 private
或 protected
成员。
如果你看一下标准库或者Boost库,你会发现这个原则应用的很多。标准库的整个 "STL" (= containers/algorithms/iterators) 部分都是基于它的。像std::set
或std::vector
这样的容器class的public接口并不像reverse
、count_if
或all_of
那样具有完整的功能.有独立的功能:
- http://en.cppreference.com/w/cpp/algorithm/reverse
- http://en.cppreference.com/w/cpp/algorithm/count
- http://en.cppreference.com/w/cpp/algorithm/all_any_none_of
- 等...
你应该在 C++ 中遵循这个优秀的例子,而不是反对它。
技术上 可以从 std::string
派生并向派生的 class 添加成员函数。但这是不好的做法。这是一个很好的问题,在这个主题上有很好的答案,包括对 Scott Meyers 或 Andrei Alexandrescu 等知名专家书籍的引用:
Why should one not derive from c++ std string class?
最后请注意,这种考虑并不是C++独有的。以Java为例。在 Java 中,最好的做法是从 classes 中派生出 only,这些 classes 被设计为基础 classes。这甚至是 Joshua Bloch 著名的 "Effective Java" 书中的一个项目。在 Java 的 String
class 的情况下,你甚至无法从中推导出来,当然,因为它是 final
。很有可能,如果 C++ 标准库是今天设计的,随着 C++11 中添加的新功能,std::string
也将是 final
(尽管 C++ 的发明者 Bjarne Stroustrup 显然已经从来都不是 final classes 的忠实粉丝,但这是另一回事了)。