vector
string的流提取
代码如下:
C++
istream& operator>>(istream& is, string& str)
{
str.clear();
int i = 0;
char buff[256];
char ch;
//is >> ch;
ch = is.get();
while (ch != ' ' && ch != '\n')
{
//str += ch;
buff[i++] = ch;
if (i == 255)//255个字符
{
buff[255] = '\0';//最后一个留给'\0'
str += buff;
i = 0;//置为零重新提取
}
ch = is.get();
}
if (i > 0)//不满255
{
buff[i] = '\0';
str += buff;
}
return is;
}
这里引入buff,在栈区开辟空间
有两个好处:
1.栈上开辟空间,比堆效率高
2.即用即销毁
总的来说,对于大的方面来说,减少扩容,不会浪费空间
用getline的情况:
string.h
C++
istream& getline(istream& is, string& str, char delim = '\n');
//delim是分隔符
string.cpp
C++
istream& getline(istream& is, string& str, char delim)
{
str.clear();
int i = 0;
char buff[256];
char ch;
ch = is.get();
while (ch != delim)
{
// 放到buff
buff[i++] = ch;
if (i == 255)
{
buff[i] = '\0';
str += buff;
i = 0;
}
ch = is.get();
}
if (i > 0)
{
buff[i] = '\0';
str += buff;
}
return is;
}
test.cpp
C++
void test_string07()
{
Tzuyu::string s1;
getline(cin, s1);
cout << s1 << endl;
getline(cin, s1, '#');//遇到#停止输入
cout << s1 << endl;
}
swap
库里面的swap
会进行深拷贝,深拷贝会重新拷贝一块空间,进行赋值,再析构销毁,但是这样的代价太大了
怎么样能使代价变小呢?
这个时候我们可以用string自己的成员函数swap
string自己的成员函数swap
现代写法
拷贝的现代写法
代码如下:
c++
//现代写法
string::string(const string& s)
{
string tmp(s._str);
swap(tmp);
}
这种写法,有点类似于资本主义压榨剩余价值,让别人来干活,传统的写法就是老老实实地开辟空间进行深拷贝,现代写法的逻辑图如下:
这里的swap是string成员里面的swap
所有的值都必须要走初始化列表
为什么这里的tmp要指向空呢?
因为这里是局部对象,出了作用域要被操作系统给回收的,索性直接置空
赋值的现代方法
C++
string& string::operator=(const string& s)
{
if (this != &s)
{
string tmp(s._str);
swap(tmp);
}
return *this;
}
更加简便地写法:
string.h
C++
string& operator=(string s);
string.cpp
C++
string& string::operator=( string s)
{
swap(s);
return *this;
}
这里是让s和s1交换空间,因为在栈区,所以会被操作系统回收空间
这里并没有效率的提升,本质是复用
引用计数+写时拷贝(了解)
写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。
引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该 资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源, 如果计数为1,说明该对象时资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有 其他对象在使用该资源。
vector
实现代码:
C++
#include<vector>
int main()
{
vector<int> v1;
vector<int> v2(10, 1);
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
// 遍历
for (size_t i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;
vector<int>::iterator it1 = v1.begin();
while (it1 != v1.end())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
for (auto e : v1)
{
cout << e << " ";
}
cout << endl;
vector<string> vstr;//不带'\0'
string s1 = "张三";//带'\0'
vstr.push_back(s1);
vstr.push_back("李四");
for (const auto& e : vstr)
{
cout << e << " ";
}
cout << endl;
vstr[0] += 'x';
vstr[0] += "apple";
//vstr[0][0]++;
vstr[0][1]++;
vstr[0][1]++;
vstr.operator[](0).operator[](1)++;//看上去像二维数组,实际上调用了两个容器,先是vector后是string
for (const auto& e : vstr)
{
cout << e << " ";
}
cout << endl;