1.1 字符串类 1.1.1C语言字符串VSC++字符串 C语言中的字符串
C语言不支持真正意义上的字符串C语言用字符串数组和一组函数实现字符串操作C语言不支持自定义类型,因此无法获得字符串类型C++中的字符串
C++ 直接支持C语言的所有概念C++中没有原生的字符串类型C++ 标准库提供了string类型 string 直接支持字符串连接string 直接支持字符串的大小比较string 直接支持子串查找和提取string 直接支持字符串的插入和替换1.1.2 字符串和数字的转换
标准库中提供了相关的类对字符串和数字进行转换字符串流类(sstream) 用于string的转换 相关头文件istringstream - 字符串输入流ostringstream - 字符串输出流1.1.3 使用方法
string ===> 数字 istringstream iss("321.12"); double num; iss>>num; 数字===》字符串 ostringstream oss; oss <<543.21 string s = oss.str();1.1.4字符串和数字的转换示例
int main() { istringstream iss("123.21"); double num; iss >> num; cout<< num<<endl; ostringstream oss; oss <<"543.21"; string s =oss.str(); cout<<s<<endl; return 0; }1.1.5 字符串循环右移
示例 “abcdefg 循环右移3位后得到efgabcd” string right_func(const string&s,unsigned int num) { string ret; unsigned int pos; num = num %s.length(); pos= s.length()-num; ret = s.substr(pos); ret += s.substr(0,pos); return ret ; } int main() { string s ="abcdefg"; string s2 = right_func(s,3); cout <<s2<<endl; return 0; } string operator >>(const string&s,unsigned int num) { string ret; unsigned int pos; num = num %s.length(); pos= s.length()-num; ret = s.substr(pos); ret += s.substr(0,pos); return ret ; } int main() { string s ="abcdefg"; string s2 = (s>>4); cout << s2<<endl; return 0; }1.1.6 字符串翻转
要求 使用 string 完成示例 “we;tonight,you” ===⇒ “ew;thginot;uoy”提示: string 类中提供了成员函数可以查找目标字符的位置1.2 数组类 1.2.1 类的对象怎样支持数组的下标访问
被忽略的事实 数组访问符是C、C++中的内循环操作符数组访问符的原生意义是数组访问和指针运算 a[n] <> *(a+n) <> *(n+a) <=====> n[a];1.2.2 数组访问操作符([])
只能通过类的成员函数重载重载函数能且只能使用一个参数可以定义不同参数的多个重载函数1.2.3数组类的优化
下面是部分代码 //数组类中的代码 int & operator[](int index) { return m_pointer[index]; } // 下面这个是常用技巧 IntArray & self() { return *this; } //在C++中能不使用指针就不使用指针 int main() { IntArray* a = IntArray::NewInstance(5); //这个代码可以通过智能指针类来将指针消除 if( a != NULL ) { IntArray& array = a->self(); //目的是减少指针的使用 cout << "array.length() = " << array.length() << endl; array[0] = 1; for(int i=0; i<array.length(); i++) { cout << array[i] << endl; } } delete a; return 0; }1.3经典问题三之一 1.3.1问题1
什么时候需要重载赋值操作符?编译器是否提供默认的赋值操作?1.3.2 答案
编译器为每个类默认重载了赋值操作符默认的赋值操作符仅仅完成浅copy当需要进行深copy的时候,必须重载复制操作符赋值操作符合copy构造函数有相同的存在意义一般性原则:重载复制操作符,必须要实现深拷贝 1.3.3 代码示例
#include <iostream> #include <sstream> #include <string> using namespace std; class Test{ private: int m_len; char* m_pointer; public: Test(const char * str) { m_len = strlen(str); m_pointer = new char[this->m_len +1]; strcpy(this->m_pointer,str); } Test(const Test& obj) { this->m_len = obj.m_len; this->m_pointer = new char[this->m_len+1]; strcpy(this->m_pointer,obj.m_pointer); } void print() { printf("m_pointer =%s\n",this->m_pointer); } ~Test() { delete[] m_pointer; } }; int main() { Test t1("zhangsan"); t1.print(); Test t2 =t1; t2.print(); Test t3("123"); t3 = t1; return 0; }上述代码报错了,下面是报错信息 为啥会这样呢? 原因就是 两个指针指向了同一个内存空间(堆上内存空间),在对象销毁的时候,会调用两次~Test(),结果同一个堆上的内存空间被释放了两次。
结论 : 重载复制操作符,必然需要实现深copy!!! -解决方案 class Test{ private: int m_len; char* m_pointer; public: Test(const char * str) { m_len = strlen(str); m_pointer = new char[this->m_len +1]; strcpy(this->m_pointer,str); } Test(const Test& obj) { this->m_len = obj.m_len; this->m_pointer = new char[this->m_len+1]; strcpy(this->m_pointer,obj.m_pointer); } void print() { printf("m_pointer =%s\n",this->m_pointer); } //修改部分 Test& operator=(const Test&obj) { if(this->m_pointer != NULL) delete[] m_pointer; this->m_len = obj.m_len; this->m_pointer = new char[this->m_len + 1]; strcpy(this->m_pointer,obj.m_pointer); return *this; } ~Test() { delete[] m_pointer; } }; int main() { Test t1("zhangsan"); t1.print(); printf("before operator =\n"); Test t3("123"); t3.print(); printf("after operator =\n"); t3 = t1; t3.print(); return 0; }1.4经典问题三之二 1.4.1问题引出
下面的代码有什么问题 string s = "123456"; const char * p = s.c_str(); cout<<p<<endl; s.append("abcdefg"); cout<<p<<endl; 结果为啥不是自己期望的。1.4.2 问题分析 1.4.3 正确做法
正确做法,是用C++的编程思想,而不是C语言和C++ 混合的思想1.5经典问题三之三 1.5.1 下面代码的输出
#include<iostream> #include<string> using namespace std; int main() { //本质是C++和C语言的思想混合开发,导致结果不是预期的那样 const char *p = "123345"; //C string s =""; //C++ s.reserve(10); for(int i =0;i<5;i++) { s[i] =p[i]; } if(!s.empty()) { cout <<s <<endl; } return 0; } 没打印内容 1.5.2分析 参考一 :狄泰软件学院C++进阶剖析 参考二 : C++ primer中文版