目录
1.深string)
1.1深拷贝的实现()
2.迭代器失效(vector--insert,earse)
3. 头文件展开问题:
1.深拷贝(string)
深浅拷贝:
浅拷贝:在拷贝构造过程中由于对自定义类型中如果存在需要在堆上开空间(new)的情况,那么在拷贝构造的时候新的对象也会指向同一个堆上的空间地址。那么在调用析构函数的时候此时就会造成对堆上new出来的对象释放两次,且指向这个空间任意一个对象进行对此空间修改的时候都会造成另一个对象的内容也随之发生改变。这个就是浅拷贝带来的问题。--解决的方法就是深拷贝
深拷贝:为了解决浅拷贝的问题,这里我们要对针对浅拷贝new的一个空间进行处理-我们只需要当拷贝构造的时候对新的对象也开辟一个同等大小的内存空间在将数据拷贝过去这样就解决了两个对象指向同一个内存空间。但这里我们应该注意在拷贝的时候我们应该要使用&传参这样可以大大减少拷贝构造。--
深拷贝的实现()
//深拷贝的实现方式1
string(const string& s)
:_str(new char [strlen(s._str)+1])// 创造一个同等大小的空间
{
strcpy(_str, s._str);
}
// 对于"="的赋值重载 为了避免空间两个大小不一致我们就先开辟一个需要存放拷贝内容大小的空间
// 然后释放之前的空间 再将需要拷贝的内容存放到新开辟空间内。
string& operator=(const string &s)
{
if(this!=s)
{
string * tmp=new string[strlen(s._str)+1]; //这里+1是为了存放\0
strcpy(tmp,s._str);
delete []_str;
_str=tmp;
}
return *this;
}
//深拷贝的另一种做法
//改进深拷贝--想法我们借用一个中间变量去完成这些事情之后将内容给到this即可
// string(string& s)
// :_str(nullptr)
// {
// string tmp(s._str);// 这里是去调用构造函数来创造空间并将s._str的内容拷贝给tmp
//
// swap(_str, tmp._str);// 将_str和tmp所指向的空间进行交换
// // 因为tmp是一个临时变量出了作用域就要调用析构函数,但是此时tmp所指向的内容已经为
// //_str所指向内容,如果没有对_str初始化那么交换后tmp指向的也是一个随机值
// //我们不能对指向随机值的空间进行析构 所以我们应先将_str赋予初始值nullptr;
// //tmp._str = nullptr;或者这样也可也
// }
string (string&s)
_str(nullptr)
{
string tmp(_s.str);
swap(_str,tmp._str);
}
// 或者
string (string&s)
{
string tmp(s._str);
swap(_str,tmp._str);
tmp._str=nullptr;
}
对于‘=’的重载
string& operator=(string s) //这里没有用&
//这里是用了拷贝函数去完成了开辟空间 在创造s的时候就回去调用
//拷贝构造这样就可以s拥有了一个新的空间且有了str的内容
{
swap(_str, s._str);
return *this;
}
2.迭代器失效(vector--insert,earse)
迭代器失效分为两种:1.由于新开辟了空间将原来的内容拷贝到新的空间上造成指向原来地址的指针成为野指针。2.没有开辟新的空间但是由于数组内容的移动,那么迭代器原来指向的内容发生了改变,那么也属于迭代器失效,对于vs下无论是那种情况对原来的迭代器解引用的时候都会报错。其中一般在vector中的earse 以及insert中出现。
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
auto begin = v.begin();
while (begin != v.end())
{
if (*begin % 2 == 0)
{
begin = v.erase(begin);// 所以为了避免迭代器失效带来的问题 所以会指向被函数调用擦除的最后一个元素之后的元素的新位置的迭代器。
}
else
{
begin++;
}
}
3. 头文件展开问题:
//假设 vector.h中使用了cout。
#include<iostream>
#include"vector.h"
//那么此时编译就会出现问题,原因是头文件在编译阶段会展开,且无论是成员变量还是成员函数都是遵守的向上
//查找 那么此时vector被展开,且vector中使用了std的成员函数那么此时向上查找就无法找到std的,那么此时就会报错。
using namespace std;
// 正确的方式
#include<iostream>
using namespace std;
#include"vector.h"
|