赞
踩
迭代器本质:指针(理解)
迭代器:正向迭代器: begin() | end() 反向迭代器: rbegin() | rend()
- //找到s中某个字符
- void TestString3()
- {
- string s("AAADEFNUIENFUIAAA");
- //找到AAA位置
- size_t pos = s.find("AAA");
- cout << pos << endl;
- }
输出0,表示0位置处为AAA
substr(pos = 0, n = npos);
从Pos位置开始,截取n个字符,如果n没有传递,表示从pos一直截取到末尾
如果都没有传递,截取整个字符
- void TestString3()
- {
- string s("124.text.cpp");
- //rfind从后面往前找 ’.’,+1找到后缀位置
- size_t pos =s.rfind('.') + 1;
-
- //从pos处截到末尾
- string postfix = s.substr(pos);
- cout << postfix << endl;
- }
- int main()
- {
- string line;
- // 不要使用cin>>line,因为会它遇到空格就结束了
- // while(cin>>line)
- while (getline(cin, line))
- {
- size_t pos = line.rfind(' ');
- cout << line.size() - pos - 1 << endl;
- }
- return 0;
- }
getline(cin,s): 获取一整行字符串,字符串中如果包含空格等空白字符也可以接收
- void Test()
- {
- string s1("abc");
- string s2("afwef");
- if (s1 < s2)
- {
- cout << "s1<s2" << endl;
- }
- else if (s1>s2)
- {
- cout << "s1>s2" << endl;
- }
- else
- {
- cout << "s1=s2" << endl;
- }
- }
浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以当继续对资源进项操作时,就会发生发生了访问违规
上述String类没有显式定义其拷贝构造函数与赋值运算符重载,此时编译器会合成默认的,当用s1构造s2时,编译器会调用默认的拷贝构造。最终导致的问题是,s1、s2共用同一块内存空间,在释放时同一块空间被释放多次而引起程序崩溃,这种拷贝方式,称为浅拷贝
如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供
正确实现String
- class String
- {
- public:
- String(const char* str = "")
- {
- if (nullptr == str)
- str == "";
- _str = new char[strlen(str) + 1];
- strcpy(_str, str);
- }
- String(const String& s)
- :_str(new char[strlen(s._str) + 1])
- {
- strcpy(_str, s._str);
- }
- String& operator=(const String& s)
- {
- if (this != &s)
- {
- char* pStr = new char[strlen(s._str) + 1];
- strcpy(pStr, s._str);
- delete[] _str;
- _str = pStr;
- }
- return *this;
- }
- ~String()
- {
- if (_str)
- {
- delete[]_str;
- _str = nullptr;
- }
- }
- private:
- char* _str;
- };
-
- void TestString()
- {
- String s1("hello");
- String s2(s1);
- String s3(s2);
- }
- int main()
- {
- TestString();
- return 0;
- }
如下,每个对象都有自己独立的空间,释放时也是,只释放自己的互不影响
减少传统代码重复,相似性代码进行优化
- class String
- {
- public:
- String(const char* str = "")
- {
- if (nullptr == str)
- {
- assert(false);
- return;
- }
- _str = new char[strlen(str) + 1];
- strcpy(_str, str);
- }
- String(const String& s)
- : _str(nullptr)//_Str可能为随机指针,要先置为空
- {
- String strTmp(s._str);
- swap(_str, strTmp._str);//交换地址
- }
- String& operator=(String s)//赋值运算符重载,先传入参数
- {
- swap(_str, s._str);//
- return *this;
- }
写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。
引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象时资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有其他对象在使用该资源
- #include <assert.h>
- #include<iostream>
- #include<string>
- using namespace std;
- namespace zx
- {
- class string
- {
- public:
- typedef char* iterator;
- ///
- // 构造
- string(const char* str = "")
- {
- if (nullptr == str)
- str = "";
-
- _size = strlen(str);
- _capacity = _size;
- _str = new char[_capacity + 1];
- strcpy(_str, str);
- }
-
- string(const string& s)
- {
- string temp(s._str);
- this->swap(temp);
- }
-
- string(size_t n, char val)
- {
- _str = new char[n + 1];
- memset(_str, val, n);
- _str[n] = '\0';
-
- _size = n;
- _capacity = n;
- }
-
- string& operator=(string s)
- {
- this->swap(s);
- return *this;
- }
-
- ~string()
- {
- if (_str)
- {
- delete[] _str;
- _str = nullptr;
- _capacity = 0;
- _size = 0;
- }
- }
-
- /
- // 迭代器
- iterator begin()
- {
- return _str;
- }
-
- iterator end()
- {
- return _str + _size;
- }
-
- /
- // 容量
- size_t size()const
- {
- return _size;
- }
-
- size_t length()const
- {
- return _size;
- }
-
- size_t capacity()const
- {
- return _capacity;
- }
-
- bool empty()const
- {
- return 0 == _size;
- }
-
- void clear()
- {
- _size = 0;
- }
-
- void resize(size_t newsize, char val)
- {
- size_t oldsize = size();
- if (newsize > oldsize)
- {
- // 有效元素个数增多
- if (newsize > capacity())
- reserve(newsize);
-
- // 多出的元素使用val填充
- memset(_str + _size, val, newsize - _size);
- }
-
- _size = newsize;
- _str[_size] = '\0';
- }
-
- void resize(size_t newsize)
- {
- resize(newsize, '\0');
- }
-
- void reserve(size_t newcapacity)
- {
- size_t oldcapacity = capacity();
- if (newcapacity > oldcapacity)
- {
- // 1. 申请新空间
- char* temp = new char[newcapacity + 1];
-
- // 2. 拷贝元素
- strncpy(temp, _str, _size);
-
- // 3. 释放旧空间
- delete[] _str;
-
- // 4. 使用新空间
- _str = temp;
-
- _capacity = newcapacity;
- _str[_size] = '\0';
- }
- }
-
-
- // 元素访问
- char& operator[](size_t index)
- {
- assert(index < _size);
- return _str[index];
- }
-
- const char& operator[](size_t index)const
- {
- assert(index < _size);
- return _str[index];
- }
-
- char& at(size_t index)
- {
- // 如果越界,抛出out_of_range的异常
- return _str[index];
- }
-
- const char& at(size_t index)const
- {
- // 如果越界,抛出out_of_range的异常
- return _str[index];
- }
-
- //
- // modify
- void push_back(char ch)
- {
- *this += ch;
- }
-
- string& operator+=(char ch)
- {
- if (_size == _capacity)
- reserve((size_t)_capacity*1.5 + 3);
-
- _str[_size] = ch;
- ++_size;
- _str[_size] = '\0';
- return *this;
- }
-
- string& operator+=(const char* str)
- {
- size_t needSpace = strlen(str);
- size_t leftSpace = capacity() - size();
- if (needSpace > leftSpace)
- {
- reserve(capacity()+ needSpace);
- }
-
- strcat(_str, str);
- _size += needSpace;
- _str[_size] = '\0';
-
- return *this;
- }
-
- string& operator+=(const string& s)
- {
- *this += s.c_str();
- return *this;
- }
-
- string& append(const char* str)
- {
- *this += str;
- return *this;
- }
-
- string& appent(const string& s)
- {
- *this += s;
- return *this;
- }
-
- string& insert(size_t pos, const string& s);
- string& erase(size_t pos = 0, size_t n = npos);
-
- void swap(string& s)
- {
- std::swap(_str, s._str);
- std::swap(_size, s._size);
- std::swap(_capacity, s._capacity);
- }
-
-
- const char* c_str()const
- {
- return _str;
- }
-
- size_t find(char ch, size_t pos = 0)const
- {
- if (pos >= _size)
- {
- return npos;
- }
-
- for (size_t i = pos; i < _size; ++i)
- {
- if (_str[i] == ch)
- return i;
- }
-
- return npos;
- }
-
- size_t rfind(char c, size_t pos = npos)
- {
- if (pos >= _size)
- {
- pos = _size-1;
- }
-
- for (int i = pos; i >= 0; --i)
- {
- if (_str[i] == c)
- return i;
- }
-
- return npos;
- }
-
- string substr(size_t pos = 0, size_t n = npos) const
- {
- // 从pos位置开始,往后借助n个字符长度
- if (pos >= _size)
- {
- return string();
- }
-
- // 从pos到字符串的末尾剩余字符个数
- n = min(n, _size - pos);
-
- string temp(n, '\0');
- size_t index = 0;
- for (size_t i = pos; i < pos+n; ++i)
- {
- temp[index++] = _str[i];
- }
-
- return temp;
- }
-
- private:
- char* _str;
- size_t _size;
- size_t _capacity;
-
- const static size_t npos = -1;
-
- friend ostream& operator<<(ostream& out, const string& s);
- };
-
- ostream& operator<<(ostream& out, const string& s)
- {
- for (size_t i = 0; i < s.size(); ++i)
- {
- cout << s[i];
- }
-
- return out;
- }
- }
-
- int main()
- {
- // TestMyString01();
- // TestMyString02();
-
- // TestMyString03();
- TestMyString04();
- _CrtDumpMemoryLeaks();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。