string类的构造,拷贝,赋值,析构函数的实现

实现分为传统版和现代版,主要区别在于现代版在拷贝构造函数和赋值运算符重载中使用了swap交换函数,代码简单了很多,但也出现了几个需要注意的问题。

  • 现代版拷贝构造函数中,this._str必须初始化为空,防止和临时变量swap之后,临时变量发生非法访问
  • 现代版赋值运算符重载中,传参方式使用传值。现代版赋值运算符重载中使用了swap,交换会使参数列表的str._str置空,所以传值,用拷贝构造函数创建一个临时的对象,不影响原来对象。

String.h

#pragma once
#include<iostream>
using namespace std;

class String
{
public:
	String(const char* str = "");
	String(const String& str);
	String& operator=(const String& str); //传统版用引用
	//String& operator=(const String str); //现代版使用了swap,交换会使str._str置空,所以传值,用拷贝构造创建一个临时的对象
	~String();


private:
	char* _str;
};

String.cpp

#include"String.h"
#include<assert.h>

//传统版:
String::String(const char* str) //缺省参数 str="" ,声明处给
{
	if (str==nullptr)
	{
		assert(false);
		return;
	}

	_str = new char[strlen(str) + 1];
	strcpy(_str, str);
}

String::String(const String& str)
	:_str(nullptr)
{
	_str =new char[strlen(str._str) + 1];
	strcpy(_str, str._str);

}

String& String::operator=(const String& str)
{
	if (this != &str)
	{
		char* pStr = new char[strlen(str._str) + 1];
		strcpy(pStr, str._str);
		delete[] _str;
		_str = pStr;
	}
	return *this;
}

String::~String()
{
	if (_str)
	{
		delete[] _str;
		_str = nullptr;
	}
}

////////////////////////////////////////////////////////////
//现代版:

String::String(const char* str) //缺省参数 str="" ,声明处给
{
	if (str == nullptr)
		str = "";

	_str = new char[strlen(str) + 1];
	strcpy(_str, str);
}

String::String(const String& str)
	:_str(nullptr) //必须初始化为空,防止swap之后,临时变量发生非法访问
{
	String temp(str._str);
	swap(_str, temp._str);
}

String& String::operator=(String str) //现代版使用了swap,交换会使str._str置空,所以传值,用拷贝构造创建一个临时的对象
{
	swap(_str, str._str);
	return *this;
}

String::~String()
{
	if (_str)
	{
		delete[] _str;
		_str = nullptr;
	}
}

越努力,越幸福!

原创文章 13 获赞 31 访问量 1246

猜你喜欢

转载自blog.csdn.net/chenzhanpeng_/article/details/106178942