string模拟实现拷贝构造operator=
个人主页:Jason_from_China-CSDN博客
所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客
所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客
string模拟实现拷贝构造operator=
拷贝构造的实现
- 这是需要实现拷贝构造的
- 什么时候需要实现拷贝构造:凡是存在资源的情况下,都是需要实现拷贝构造的,简单的可以理解为只要是需要手动实现析构函数的,都是需要实现拷贝构造的
- 这里本来是需要先实现substr取出字符串
- 但是,substr取出字符串是需要实现深拷贝的,如果我们不实现拷贝构造那么就会导致只是实现浅拷贝,资源是没有办法拷贝成功的,所以我们是需要实现拷贝构造的
//拷贝构造 string& string::operator=(const string& s) { //这里是不能自己给自己拷贝构造的 //因为我们首先就是进行函数的析构,这样就会导致我们无法找到数值 if (this != &s) { delete[] _str; _str = new char[s._capacity + 1]; strcpy(_str, s._str); _size = s._size; _capacity = s._capacity; return *this; } }
代码解释:
- 拷贝构造我们实现的是把传递过来的对象拷贝到this指向的对象里面,注意这里是对象,不是字符串
- 首先销毁原来的空间,然后创建一个和当前传递过来对象一样大小的空间
- 把字符串拷贝到里面,然后同步_size,_capacity
- 最后返回这一个this指向的对象
注意事项:
- 这里我们可以看出来我们是有实现条件的,因为我们不能自己给赋值
- 原因:delete[] _str;首先我们就是销毁对象
- 我们销毁对象之后我们是没办法继续进行赋值的,所以我们是不能给自己赋值
- 除非我们改变代码逻辑,但是没什么必要,还会变得麻烦
string模拟实现substr
取出字符串,这里还是比较简单的,但是这里是有问题的,我们看得出来在C++文档里面取出字符串实际上是取出整个对象,不是取出的只是字符串,所以是需要实现拷贝构造的
//取出字符串实现 string string::substr(size_t pos, size_t len) { //取出字符串的问题设计深浅拷贝的问题,这里我们需要优先实现拷贝构造函数 //关于拷贝构造函数的实现,我们需要注意的是,拷贝构造实现的是深拷贝、 //因为我们创建的空间赋值后指向的是同一个空间,所以我们需要实现拷贝构造 //因为存在资源的话,就需要我们手动实现拷贝构造。 //否则就会指向一个空间,从而导致析构析构两次 assert(pos >= 0); 首先我们创建一个空间,然后对空间进行扩容 //Test::string tmp; //tmp.reserve(len); //这里可以不用优先扩容,我们可以优先计算出来空间需要开辟的大小 if (len >= _size - pos) { len = _size - pos; } //首先我们创建一个空间,然后对空间进行扩容 Test::string tmp; tmp.reserve(len); for (size_t i = 0; i < len; i++) { //tmp[i] = _str[pos + i];//这里插入会依旧导致需要继续添加\0,所以我们采取+=的复用,更加方便一点 tmp+= _str[pos + i]; } tmp._size = len; //此时完成了资源的拷贝也就是深拷贝,那么此时返回就不会报错 //注意完成浅拷贝的时候,返回报错不是因为空间销毁,而是因为析构函数析构两次,所以才会导致报错 return tmp; }
取出字符串的测试 Test::string s7(" hello word hello word hello word hello word "); Test::string ret1 = s7.substr(0, 10); cout << "substr查找字符的测试:" << ret1.c_str() << endl;
代码解释:
- 断言
- 我们需要判断取出的字符串的实际长度是多少
- 创建一个空间,扩容到相应的长度
- tmp+= _str[pos + i];,这里我们把从pos位置开始的字符串追加到tmp里面
- 更新字符串的长度
注意事项:
- 这里可能会有小伙伴说了,这里也没有遇见需要实现拷贝构造的情况啊,这个时候我们查看测试用例
- 首先我们的函数实现返回参数返回的是一个临时对象,这个临时对象是需要接收值来延长生命周期的Test::string ret1 = s7.substr(0, 10);,所以这个时候拷贝构造就使用上了
- 如果不实现拷贝构造,对象的生命周期没有延长,就会导致对象出去函数就会直接被销毁,因为我们是在函数里面创建的对象