实现分为传统版和现代版,主要区别在于现代版在拷贝构造函数和赋值运算符重载中使用了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;
}
}
越努力,越幸福!