首先呢,对于一个类来说我们必须要知道它的六大默认成员函数,此篇重点讲其中的构造、拷贝、赋值和析构函数的实现。
传统写法
string类的构造函数
String() //无参的构造函数
:_str(new char[1])
{
_str[0] = '\0';
}
String(char* str) //带参的构造函数
:_str(new char[strlen(str)+1])
{
strcpy(_str, str);
}
当然,我们也可以把上面的两段代码写在一起,利用缺省值去简化代码。
String(char* str = "") //需要注意一点,作为一个字符串,当里面没有值的时候,应该储存的有一个\0作为结束符
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
拷贝构造函数
// copy(s1)
//拷贝需要注意的是深浅拷贝问题,对于字符串来说不是简单的值拷贝,如果不进行处理只做简单的值拷贝,会造成的问题就是两个指针指向的是同一块空间,那么在调用析构函数的时候就会出现很大的问题,一块空间是不能被释放两次的
String(const String& s)
:_str(new char[strlen(s._str)+1])
{
strcpy(_str, s._str);
}
赋值
// copy = s2
String& operator=(const String& s)
{
if (this != &s) //要注意自己给自己赋值是没有意义的,所以要判断一下
{
delete[] _str;
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
}
return *this;
}
析构函数
~String()
{
if (_str)
delete[] _str;
}
现代写法
string类的构造函数
String(char* str = "")
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
拷贝构造函数
// copy(s1)
String(const String& s)
:_str(nullptr)
{
String tmp(s._str);
swap(_str, tmp._str);
}
赋值
// copy = s2;
String& operator=(String s)
{
swap(_str, s._str);
return *this;
}
析构函数
~String()
{
if (_str)
delete[] _str;
}
以下是笔者的代码
//#include <iostream>
//#include <string>
//#include <assert.h>
//using namespace std;
//
传统写法
//namespace STR
//{
// class String
// {
// public:
// /* String()
// :_str(new char[1])
// {
// _str[0] = '\0';
// }
//
// String(char* str)
// :_str(new char[strlen(str)+1])
// {
// strcpy(_str, str);
// }*/
//
// String(char* str = "")
// :_str(new char[strlen(str) + 1])
// {
// strcpy(_str, str);
// }
//
// // copy(s1)
// String(const String& s)
// :_str(new char[strlen(s._str)+1])
// {
// strcpy(_str, s._str);
// }
//
// // copy = s2
// String& operator=(const String& s)
// {
// if (this != &s)
// {
// delete[] _str;
// _str = new char[strlen(s._str) + 1];
// strcpy(_str, s._str);
// }
//
// return *this;
// }
//
// ~String()
// {
// if (_str)
// delete[] _str;
// }
//
// char* c_str()
// {
// return _str;
// }
//
// char& operator[](size_t pos)
// {
// return _str[pos];
// }
//
// size_t Size()
// {
// return strlen(_str);
// }
//
// private:
// char* _str;
// };
//
// void TestString1()
// {
// String s1(nullptr);
// String s2("hello");
// s2[0] = 'x';
//
// for (size_t i = 0; i < s2.Size(); ++i)
// {
// cout << s2[i] << " ";
// }
// cout << endl;
//
// cout << s1.c_str() << endl;
// cout << s2.c_str() << endl;
// }
//
// // 深浅拷贝
// //
// void TestString2()
// {
// String s1("hello");
// String copy(s1);
// String s2("world");
//
// cout << s1.c_str() << endl;
// cout << copy.c_str() << endl;
//
// copy = s2;
// cout << copy.c_str() << endl;
// }
//}
// 现代写法
namespace STR
{
class String
{
public:
String(char* str = "")
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
// copy(s1)
String(const String& s)
:_str(nullptr)
{
String tmp(s._str);
swap(_str, tmp._str);
}
// copy = s2
/* String& operator=(const String& s)
{
if (this != &s)
{
String tmp(s._str);
swap(_str, tmp._str);
}
return *this;
}*/
// copy = s2;
String& operator=(String s)
{
swap(_str, s._str);
return *this;
}
~String()
{
if (_str)
delete[] _str;
}
char* c_str()
{
return _str;
}
char& operator[](size_t pos)
{
return _str[pos];
}
size_t Size()
{
return strlen(_str);
}
private:
char* _str;
};
void TestString1()
{
String s1(nullptr);
String s2("hello");
s2[0] = 'x';
for (size_t i = 0; i < s2.Size(); ++i)
{
cout << s2[i] << " ";
}
cout << endl;
cout << s1.c_str() << endl;
cout << s2.c_str() << endl;
}
void TestString2()
{
String s1("hello");
String copy(s1);
String s2("world");
cout << s1.c_str() << endl;
cout << copy.c_str() << endl;
copy = s2;
cout << copy.c_str() << endl;
}
}