浅拷贝
// 浅拷贝:
class String
{
public:
String(const char *str) : _str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
String(const String &s) : _str(s._str)
{
// 浅拷贝的方式就是将类中的指针指向新的指针
// 这样就是实现了两个执政指向同一空间
// 缺点1:通过类1修改空间内容,类2的内容也回改变
// 缺点2:如果通过类1释放该空间过后,再通过类2释放空间就会出错
}
String &operator=(const String &s)
{
if (this != &s)
{
_str = s._str;
}
//返回引用是为了连续的赋值
return *this;
}
~String()
{
cout << "String析构" << endl;
// 释放申请来的空间
if (_str)
{
delete[] _str;
}
// 防止野指针的出现
_str = NULL;
}
char *_str_get()
{
return this->_str;
}
void _str_set(const char *s)
{
strcpy(_str, s);
}
private:
char *_str;
};
浅拷贝的方式就是将类中的指针指向新的指针
这样就是实现了两个执政指向同一空间
问题1:通过类1修改空间内容,类2的内容也回改变
问题2:如果通过类1释放该空间过后,再通过类2释放空间就会出错
深拷贝的写法
// 深拷贝:
class MyString
{
public:
MyString(const char *s) : _str(new char[strlen(s) + 1])
{
strcpy(_str, s);
}
MyString(const MyString &s) : _str(NULL)
{
MyString temp(s._str);
swap(_str, temp._str);
}
MyString &operator=(const MyString &s)
{
// 深拷贝的方式就是通过重新构造一个局部类temp获取新的指针
// 然后通过swap交换两个类的指针,相当于使_str重新指向一个新开辟的空间
// 因为是局部类,执行完函数过后相应的就会被释放掉
if (this != &s)
{
MyString temp(s._str);
swap(_str, temp._str);
}
//返回引用是为了连续的赋值
return *this;
}
~MyString()
{
cout << "MyString析构" << endl;
if (_str)
{
delete[] _str;
}
_str = NULL;
}
char *_str_get()
{
return this->_str;
}
void _str_set(const char *s)
{
strcpy(_str, s);
}
private:
char *_str;
};
深拷贝的方式就是通过重新构造一个局部类temp获取新的指针
然后通过swap交换两个类的指针,相当于使_str重新指向一个新开辟的空间
因为是局部类,执行完函数过后相应的就会被释放掉
完整程序
#include <iostream>
#include <string.h>
using namespace std;
// 浅拷贝:
class String
{
public:
String(const char *str) : _str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
String(const String &s) : _str(s._str)
{
// 浅拷贝的方式就是将类中的指针指向新的指针
// 这样就是实现了两个执政指向同一空间
// 缺点1:通过类1修改空间内容,类2的内容也回改变
// 缺点2:如果通过类1释放该空间过后,再通过类2释放空间就会出错
}
String &operator=(const String &s)
{
if (this != &s)
{
_str = s._str;
}
//返回引用是为了连续的赋值
return *this;
}
~String()
{
cout << "String析构" << endl;
// 释放申请来的空间
if (_str)
{
delete[] _str;
}
// 防止野指针的出现
_str = NULL;
}
char *_str_get()
{
return this->_str;
}
void _str_set(const char *s)
{
strcpy(_str, s);
}
private:
char *_str;
};
// 深拷贝:
class MyString
{
public:
MyString(const char *s) : _str(new char[strlen(s) + 1])
{
strcpy(_str, s);
}
MyString(const MyString &s) : _str(NULL)
{
MyString temp(s._str);
swap(_str, temp._str);
}
MyString &operator=(const MyString &s)
{
// 深拷贝的方式就是通过重新构造一个局部类temp获取新的指针
// 然后通过swap交换两个类的指针,相当于使_str重新指向一个新开辟的空间
// 因为是局部类,执行完函数过后相应的就会被释放掉
if (this != &s)
{
MyString temp(s._str);
swap(_str, temp._str);
}
//返回引用是为了连续的赋值
return *this;
}
~MyString()
{
cout << "MyString析构" << endl;
if (_str)
{
delete[] _str;
}
_str = NULL;
}
char *_str_get()
{
return this->_str;
}
void _str_set(const char *s)
{
strcpy(_str, s);
}
private:
char *_str;
};
int main(int argc, char **argv)
{
// 浅拷贝
String x_str("hello");
String y_str(x_str);
char *per = x_str._str_get();
cout << "x_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl;
per = y_str._str_get();
cout << "y_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl;
cout << "x_str:" << x_str._str_get() << endl;
cout << "y_str:" << y_str._str_get() << endl;
y_str._str_set("aaa");
cout << "x_str:" << x_str._str_get() << endl;
cout << "y_str:" << y_str._str_get() << endl;
// 深拷贝
MyString m_str("world");
MyString n_str(m_str);
per = m_str._str_get();
cout << "m_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl;
per = n_str._str_get();
cout << "n_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl;
cout << "m_str:" << m_str._str_get() << endl;
cout << "n_str:" << n_str._str_get() << endl;
m_str._str_set("bbb");
cout << "m_str:" << m_str._str_get() << endl;
cout << "n_str:" << n_str._str_get() << endl;
// 两个指针指向不同的空间
return 0;
}