前言:大佬写博客给别人看,菜鸟写博客给自己看,我是菜鸟
模拟实现:类的构造、拷贝构造、赋值运算符重载、析构函数
1.传统写法
namespace jc
{
class String
{
public:
String(const char* str = "")
{
if (str != nullptr)
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
}
String(const String& s)
:_str(new char(strlen(s._str)+1))
{
strcpy(_str, s._str);
}
String& operator=(const String& s)
{
if (this != &s)
{
char* ptr = new char[strlen(s._str) + 1];
strcpy(ptr, s._str);
delete[] _str;
_str = ptr;
}
return *this;
}
~String()
{
if (_str != nullptr)
{
delete _str;
_str = nullptr;
}
}
private:
char* _str;
};
2.现代写法
现代写法的区别在拷贝构造和赋值运算符重载上做了修改
思路:
不再是传统的通过new一块内存空间,再通过strcpy()拷贝数据。
而是通过swap()函数,交换两个_str的指针指向,从而达到拷贝的目的。其次由于c++中临时对象具有常性这一特性,在调用完成后,会自动调用析构函数释放空间,避免内存泄漏
String(const String& s)
:_str(nullptr)
{
String strTMP(s._str);
swap(_str, strTMP._str);
}
String& operator=(String s)
{
swap(_str, s._str);
return *this;
}
分析:
👉:对于拷贝构造而言,函数内创建了一个临时对象,并初始化。调用swap函数,将数据拷贝给_str。因为strTMP,属于临时对象,因此在出函数时,会调用其析构函数,避免内存泄漏。
👉:对于赋值运算符重载而言,形参通过传值方式(string s)接收实参,系统会先创建一个临时对象。用swap函数,将数据拷贝给_str。return后,会自动调用临时对象s的析构函数,从而避免内存泄漏的问题。
复习:传引用调用,减少了临时拷贝这个环节,从而提高效率,在某些场合。
优点:
👉:避免了程序员去另外分析所需开辟空间的大小,减少失误。
👉:避免了内存泄露的问题