1.string类的构造方法
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
// 模板类string的构造方法
// 1. 没有参数的构造方法
string str1;
str1 = "超人";
cout << "str1 = " << str1 << endl;
// 2. string(const char* s) 参数为常量的字符指针
const char s[] = "hello world";
string str2_1(s);
cout << "str2_1 = " << str2_1 << endl;
string str2_2("世界你好.");
cout << "str2_2 = " << str2_2 << endl;
// 3. string(size_type n, char c) :将n个c连成字符串
string str3(12, 'd');
cout << "str3 = " << str3 << endl; // dddddddddddd
// 4. string(const string &str) 参数是string类型
string str4(str2_1);
cout << "str4 = " << str4 << endl; // hello world
// 5. string(const char* s, size_type n) // 截取s指向的字符串的前n个字符
char greeting[] = "hello bill";
string str5(greeting, 5);
cout << "str5 = " << str5 << endl; // hello
// 6. template<class Iter>string(Iter begin, Iter end) // 截取begin和end之间的字符,不包括end
string str6(greeting + 6, greeting + 10); //greeting指向“h”,+6后指向“b”
string str6_1(&str2_1[0] + 1, &str2_1[0] + 5);
cout << "str6 = " << str6 << endl; // bill
cout << "str6_1 = " << str6_1 << endl; // ello
// 7. string(const string& str, size_type pos, size_type npos) //参数1:字符串 参数2:截取开始的位置 参数3:截取长度,若此参数不指定,则截取到末尾
string str7_1(str2_1, 6);
cout << "str7_1 = " << str7_1 << endl; // world
string str7_2(str2_1, 6, 2);
cout << "str7_2 = " << str7_2 << endl; // wo
// 8.(C++ 11)string(initialier_list<char> list) 参数为字符列表
string str8_1 = {'H', 'a', 'c'};
string str8_2 {'a','b','c'};
cout << "str8_1 = " << str8_1 << endl; // Hac
cout << "str8_2 = " << str8_2 << endl; // abc
return 0;
}
2.输入string类型的值
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
// 输入string类型的值
char cInput[20]; // 字符数组
// cin >> cInput; // 读一个单词,空格后的都不要了,因为cInput[20],所以输入单词的长度最大为19
// cin.getline(cInput, 20); // 读一行,空格后的还要, \n(回车)这个符号不要了
// cin.get(cInput, 20); // 读一行 将 \n(回车)也加入到读取队列中
// cout << cInput << endl;
// cin.getline(cInput, 20, ':');
// cout << cInput << endl;
string sInput; // 字符串
// cin >> sInput; // 读一个单词
// getline(cin, sInput);
// cout << sInput << endl; // 读一行
getline(cin, sInput, ';'); // 定义了第三个参数后,输入结束不再以\n(空格)为标志,而是以第三个参数为标志
cout << sInput << endl;
return 0;
}
3.string值的比较和定位
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
// string的基本功能
// 1. 字符串的比较
// 2. 字符串的定位
// 1. 字符串的比较,先根据ASCII值,如果ASCII值都一样,再根据长度,
string str1("hello");
string str2("world");
if(str1 > str2)
{
cout << "str1 > str2" << endl;
}
else if(str1 < str2)
{
cout << "str1 < str2" << endl; // str1 < str2
}
else
{
cout << "str1 == str2" << endl;
}
char str3[20] = "I love you.";
if(str3 < str1)
{
cout << "str3 < str1" << endl; // str3 < str1,大写字符的ASCII比小写的小
}
// 2. 字符串的定位
cout << string::npos << endl; // 本系统允许输入字符串的最大值
cout << "str1.find(\"l\") = " << str1.find("l") << endl; // 2 返回str1中第一个l的位置的索引(从0开始)
cout << "str1.find(\"l\", 3) = " << str1.find("l", 3) << endl; // 3 从第三个(0开始数)位置开始搜索l
if(str1.find("l", 4) == string::npos)
{
cout << "未查到字符串" << endl;
}
cout << "str1.find(\"l\", 4) = " << str1.find("l", 4) << endl; // "未查到字符串"
cout << "str1.rfind(\"l\") = " << str1.rfind("l") << endl; // 3 从后往前查找,返回该位置从前往后的索引
// 查找参数值中每一个字符在原字符串中第一个出现的位置
cout << "str2.find_first_of(\"hero\") = " << str2.find_first_of("hero") << endl; // 1
// 查找参数值中每一个字符在原字符串中第一个出现的位置(从右往左找)
cout << "str2.find_last_of(\"hero\") = " << str2.find_last_of("hero") << endl; // 2
// 查找原字符串中的每一个字符,在参数值中,第一次不出现的位置
cout << "str2.find_first_not_of(\"whero\") = " << str2.find_first_not_of("hero") << endl; // 0
return 0;
}
4.获取string的尺寸和分配的空间的大小
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
// 获取string的尺寸和已分配内存空间的尺寸
string empty;
string small = "hello";
string large = "获取string的尺寸和已分配内存空间的尺寸";
cout << "empty size is " << empty.size() << endl; // 0
cout << "small size is " << small.size() << endl; // 5(字节)
cout << "large size is " << large.size() << endl; // 54 16个汉字+string,每个汉字占3字节
cout << "empty capacity is " << empty.capacity() << endl; // 22 在不同的编译环境,初始的空间尺寸不一定
cout << "small capacity is " << small.capacity() << endl; // 22,small占用的不超过22
cout << "large capacity is " << large.capacity() << endl; // 63(分配的内存是16的倍数减1),比54大的16的倍数减一,就是63了
empty.resize(80); // 给empty设置尺寸 16 *6 = 96
cout << "empty capacity is " << empty.capacity() << endl; // 95
return 0;
}
5.智能指针的基本用法
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass()
{
cout << "MyClass对象被创建." << endl;
}
~MyClass()
{
cout << "MyClass对象被销毁." << endl;
}
string getName()
{
return "Bill";
}
};
void process1()
{
auto myClass1 = new MyClass();
cout << myClass1->getName() << endl;
int i = 10;
if(i > 1)
{
throw "出错了"; //若在此处抛出了异常,则不会再执行下面的delete myClass1;,进而导致内存泄漏
}
delete myClass1;
}
void process2()
{
auto_ptr<MyClass> myClass1(new MyClass()); // 后面不需要跟着delete来释放内存空间了
cout << myClass1->getName() << endl; // 打印:MyClass对象被创建. Bill MyClass对象被销毁.
}
void process3()
{
shared_ptr<MyClass> myClass1(new MyClass());
cout << myClass1->getName() << endl; // 结果同上
}
void process4()
{
unique_ptr<MyClass> myClass1(new MyClass());
cout << myClass1->getName() << endl; // 结果同上
}
int main(int argc, const char * argv[]) {
// 智能指针的基本用法,当保存指针的变量释放了,那么这个指针指向的内存空间同样也会被释放
// C++ 98: auto_ptr
// C++ 11: shared_ptr、unique_ptr
//process1();
// process2();
// process3();
process4();
return 0;
}
6.auto_ptr、shared_ptr和unique_ptr的区别和应用场景
#include <iostream>
using namespace std;
void process1()
{
auto_ptr<string> str1(new string("hello world")); // *str1是hello world
auto_ptr<string> str2;
str2 = str1; // 所有权转移
cout << *str2 << endl; // 输出*str1会抛出异常,因为所有权转移,str1所指向的对象指针为null
}
void process2()
{
unique_ptr<string> str1(new string("hello world"));
unique_ptr<string> str2;
// str2 = str1; // 编译时就会出错
cout << *str2 << endl;
}
void process3()
{
shared_ptr<string> str1(new string("hello world"));
shared_ptr<string> str2;
str2 = str1;
cout << *str1 << endl; // str1和str2都能打印hello world
}
int main(int argc, const char * argv[]) {
// auto_ptr、shared_ptr和unique_ptr的区别和应用场景
//process1();
// 如果两个或多个指针同时指向一个内存区域,那么当这些指针释放时,这块内存区域就会被释放多次,为了解决这一问题有三种方法:
// 1. 深度复制:复制智能指针时指针指向的对象一起复制
// 2. 所有权(auto_ptr和unique_ptr):对于一个特定对象,同时只能有一个智能指针拥有它。如果发生智能指针赋值操作,所有权会转移
// 3. 智能指针计数器(shared_ptr):一个特定对象可以被多个智能指针引用。智能指针维护一个智能指针计数器,如果某个指针过期,计数器
// 就会减1. 直到计数器为0,智能指针指向的对象才会被释放。
process3();
return 0;
}
7.unique_ptr与临时右值
#include <iostream>
using namespace std;
unique_ptr<string> getString() // 函数getString的返回值类型是指向string的智能指针
{
unique_ptr<string> str(new string("女神"));
return str;
}
int main(int argc, const char * argv[]) {
// unique_ptr与临时右值;
// 如果右侧值在当前作用域是永久的unique_ptr智能指针,不允许将其赋值给其他的智能指针,如果右侧是临时的智能指针,则允许赋值
unique_ptr<string> str1(new string("超人"));
// unique_ptr<string> str2 = str1; // 会报错
unique_ptr<string> str3 = getString(); // 等号右侧是函数的返回值(临时变量),可以赋值
cout << *str3 << endl;
return 0;
}
8.如何选择智能指针
#include <iostream>
using namespace std;
void sortStr(shared_ptr<string> strArray[], size_t size) // 字符串排序函数,参数2是数组长度
{
for(size_t i = 0; i < size - 2; i++)
{
for(size_t j = 0; j < size -1 -i; j++)
{
if(*strArray[j] > *strArray[j + 1])
{
shared_ptr<string> tmp;
tmp = strArray[j];
strArray[j] = strArray[j + 1];
strArray[j + 1] = tmp;
}
}
}
}
int main(int argc, const char * argv[]) {
// 如何选择智能指针
// auto_ptr、unique_ptr和shared_ptr
// auto_ptr并不建议使用
shared_ptr<string> strArray[]{
shared_ptr<string>(new string("abc")),
shared_ptr<string>(new string("xyz")),
shared_ptr<string>(new string("hero")),
shared_ptr<string>(new string("ccc")),
shared_ptr<string>(new string("bcd"))
};
size_t size = 5;
sortStr(strArray, size);
for(size_t i = 0; i < size;i++)
{
cout << *strArray[i] << endl;
}
return 0;
}