【C++】string类的使用③(非成员函数重载Non-member function overloads)

简介: 这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `<`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。

==replace==

在这里插入图片描述

函数大体功能是将当前对象串中的一段字符串或字符用另一段字符串或字符替换。

(1) string
string& replace (size_t pos, size_t len, const string& str);
string& replace (iterator i1, iterator i2, const string& str);
将当前对象相应位置替换为str
(2) substring
string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);
将当前对象相应位置替换为str对象由subpos位置开始,跨越sublen的子串(如果len过大超出串的范围,则取到str的末尾)
(3) c-string
string& replace (size_t pos, size_t len, const char* s);
string& replace (iterator i1, iterator i2, const char* s);
将当前对象相应位置替换为s指向(由'\0'字符结尾)的字符串
(4) buffer
string& replace (size_t pos, size_t len, const char* s, size_t n);
string& replace (iterator i1, iterator i2, const char* s, size_t n);
将当前对象相应位置替换为s指向的前n个字符组成字符串
(5) fill
string& replace (size_t pos, size_t len, size_t n, char c);
string& replace (iterator i1, iterator i2, size_t n, char c);
将当前对象相应位置替换为n个char类型的c字符
(6) range
template <class InputIterator>
string& replace (iterator i1, iterator i2, InputIterator first, InputIterator last);
将当前对象相应位置替换为迭代器区间[first,last)内的字符序列*

使用案例:

// replacing in a string
#include <iostream>
#include <string>
using namespace std;
int main()
{
   
   
    string base = "this is a test string.";
    string str2 = "n example";
    string str3 = "sample phrase";
    string str4 = "useful.";

    // replace signatures used in the same order as described above:

    // Using positions:                 0123456789*123456789*12345
    string str = base;           // "this is a test string."
    str.replace(9, 5, str2);          // "this is an example string." (1)
    str.replace(19, 6, str3, 7, 6);     // "this is an example phrase." (2)
    str.replace(8, 10, "just a");     // "this is just a phrase."     (3)
    str.replace(8, 6, "a shorty", 7);  // "this is a short phrase."    (4)
    str.replace(22, 1, 3, '!');        // "this is a short phrase!!!"  (5)

    // Using iterators:                                               0123456789*123456789*
    str.replace(str.begin(), str.end() - 3, str3);                    // "sample phrase!!!"      (1)
    str.replace(str.begin(), str.begin() + 6, "replace");             // "replace phrase!!!"     (3)
    str.replace(str.begin() + 8, str.begin() + 14, "is coolness", 7);    // "replace is cool!!!"    (4)
    str.replace(str.begin() + 12, str.end() - 4, 4, 'o');                // "replace is cooool!!!"  (5)
    str.replace(str.begin() + 11, str.end(), str4.begin(), str4.end());// "replace is useful."    (6)
    cout << str << '\n';
    return 0;
}
AI 代码解读

在这里插入图片描述

==swap==

在这里插入图片描述
void swap (string& str);
交换两个string对象的内容

使用案例:

#include<iostream>
#include<string>
using namespace std;
int main()
{
   
   
    string str1("hello");
    string str2("world");
    cout << str1 << endl;
    cout << str2 << endl;

    str1.swap(str2);

    cout << endl;
    cout << str1 << endl;
    cout << str2 << endl;
    return 0;
}
AI 代码解读

在这里插入图片描述

注:此函数比algorithm提供的swap交换更优,是string交换的最优方式。故交换string对象时尽量使用此方法。

🔥非成员函数重载(Non-member function overloads)

在这里插入图片描述

非成员函数重载,是作为string类的友元函数,在类的外面定义和实现,通过类型来匹配非成员函数。

==operator+==

在这里插入图片描述
这里其实不用过多赘述,六个重载实现了string对象相加的功能(string对象+字符串,string对象+字符,字符串+string对象,字符+string对象,string对象+string对象)。

注:没有 -> 字符串+字符串

代码案例:

// concatenating strings
#include <iostream>
#include <string>
using namespace std;
int main()
{
   
   
    string firstlevel("com");
    string secondlevel("cplusplus");
    string scheme("http://");
    string hostname;
    string url;

    hostname = "www." + secondlevel + '.' + firstlevel;
    url = scheme + hostname;

    cout << url << '\n';
    return 0;
}
AI 代码解读

在这里插入图片描述

==relation operators(string)==

在这里插入图片描述

重载了string对象之间进行比较大小的功能,比较规则就是字典序。

代码案例:

// string comparisons
#include <iostream>
#include <vector>
using namespace std;
int main()
{
   
   
    string foo = "alpha";
    string bar = "beta";

    if (foo == bar) cout << "foo and bar are equal\n";
    if (foo != bar) cout << "foo and bar are not equal\n";
    if (foo < bar) cout << "foo is less than bar\n";
    if (foo > bar) cout << "foo is greater than bar\n";
    if (foo <= bar) cout << "foo is less than or equal to bar\n";
    if (foo >= bar) cout << "foo is greater than or equal to bar\n";

    return 0;
}
AI 代码解读

在这里插入图片描述

==swap(string)==

在这里插入图片描述
交换strirng对象

代码案例:

#include<iostream>
#include<string>
using namespace std;
int main()
{
   
   
    string str1("hello");
    string str2("world");
    cout << str1 << endl;
    cout << str2 << endl;

    swap(str1, str2);

    cout << endl;
    cout << str1 << endl;
    cout << str2 << endl;
    return 0;
}
AI 代码解读

在这里插入图片描述

此非成员函数也可以实现string对象的交换,但是这个实现与重载在string类中的不同,string对象在交换串的时候是改变指针指向交换的。而这里的swap是使用tmp存储临时对象的方式实现交换,增大了内存开销。

==流插入和流提取重载==

在这里插入图片描述
控制台输入将内容读取到string对象中
在这里插入图片描述
将内容输入到控制台

使用案例:

// inserting strings into output streams
#include <iostream>
#include <string>
using namespace std;
int main()
{
   
   
    string str;
    cin >> str;
    cout << str << '\n';
    return 0;
}
AI 代码解读

在这里插入图片描述

注:cin的读入是按照空格和换行进行分隔的,当你输入hello world时,使用上面的cin只能读取到hello。
如下:
在这里插入图片描述
当面对这种情况时,就需要我们的getline出手了。

==getline==

在这里插入图片描述
功能和cin相同,但可以通过此函数更改字符串读取时的分隔方式。

(1)
istream& getline (istream& is, string& str, char delim);
当你传第三个参数时,调用此函数,会以delim为分隔符进行分隔
(2)
istream& getline (istream& is, string& str);
当不传第三个参数,会默认以'\n'为分隔符

使用案例:

// extract to string
#include <iostream>
#include <string>
using namespace std;
int main()
{
   
   
    string name;

    cout << "Please, enter your full name: ";
    getline(cin, name);
    cout << "Hello, " << name << "!\n";

    return 0;
}
AI 代码解读

在这里插入图片描述

结语

本篇博客,介绍了关于string的修改器,能修改string串中的内容;以及非成员函数的重载,实现了一些成员函数无法完成的功能和任务
博主会继续分享关于string类的使用以及STL更多的内容,感谢大家的支持。♥

目录
打赏
0
1
1
0
15
分享
相关文章
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
48 12
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
55 16
|
2月前
|
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
131 6
|
4月前
|
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
119 19
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等