string类的实现
C++使用起来非常方便,原因的它里面包含的类,这种面向对象的思想让我们编程变得异常方便。今天我们来实现一个string类,这
个类主要的作用就是在C++中灵活的使用字符串。现在我们一步一步的来,一个类首先应该写出他的成员,和它的默认函数,构造函
数和析构函数显得尤为重要,首先我们来看构造函数。
//构造函数
String(char *str ="")
:_str(new char[strlen(str)+1])
{
strcpy(_str, str);
cout << "String(const char *str)" << endl;
}
//拷贝构造函数
String(const String& s)
:_str(new char[strlen(s._str)+1])
{
cout << "String(const String& s)" << endl;
strcpy(_str,s._str);
}
这个时候我们分析代码为什么。
这里我们用的是深拷贝的知识进行构造函数和拷贝构造函数。
深浅拷贝的问题可以看我的这个博客:
http://blog.csdn.net/dawn_sf/article/details/61633384
里面有深浅拷贝的问题。
现在我们用第二种方法 用写时拷贝的知识进行string类的构造
具体的可以看我这个博客:
http://blog.csdn.net/dawn_sf/article/details/66522352
里面有写时拷贝详细的讲解
接下来使我们的析构函数:
~String()
{
cout << "!String()" << endl;
if (_str != NULL)
{
delete[] _str;
}
}
这个函数挺简单的就不说了。
现在看看拷贝构造和构造运行的结果:
int main()
{
String str1("abcdefg");
cout << str1 << endl;
String str2(str1);
cout << str2 << endl;
return 0;
}
这里没问题吧,一次构造 一次拷贝构造,2次析构,并且打印出来内容也相等。
现在还有一个运算符重载了。我们只需要重载一个“=”号就可以,其他方法相似。
String& operator=(const String& s)
{
cout << "Stndl;ring& operator=(const String& s)" << endl;
if (&s != this)
{
delete[] _str;
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
strcpy(_str, s._str);
}
return *this;
}
除过这种方法还有一种很牛逼的方法,但是不容易思考。
下面来看看这个方法:
String& operator=(String& s)
{
cout << "Stndl;ring& operator=(const String& s)" << endl;
std::swap(_str, s._str);
return *this;
}
一个基本的String类已经被我构造起来了,最后我们看一看程序能不能跑过去:
# define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<Windows.h>
using namespace std;
class String
{
friend ostream& operator<<(ostream& os, const String& s);
public:
//构造函数
String(char *str ="")
:_str(new char[strlen(str)+1])
{
strcpy(_str, str);
cout << "String(const char *str)" << endl;
}
//拷贝构造函数
String(const String& s)
:_str(new char[strlen(s._str)+1])
{
cout << "String(const String& s)" << endl;
strcpy(_str,s._str);
}
String& operator=(String& s)
{
cout << "Stndl;ring& operator=(const String& s)" << endl;
std::swap(_str, s._str);
return *this;
}
~String()
{
cout << "~String()" << endl;
if (_str != NULL)
{
delete[] _str;
}
}
private:
char *_str;
};
ostream& operator<<(ostream& os, const String& s)
{
os << s._str;
return os;
}
int main()
{
String str1("abcdefg");
cout << str1 << endl;;
String str2(str1);
String str3;
str3 = str2;
cout << str3 << endl;
return 0;
}
可以看出来没有任何问题,先构造str1,然后打印,在拷贝构造str2,再构造str3,然后调用运算符重
载给str3赋值,然后打印str3,最后从str3到str1依次析构,好完美~~。