C++ 的new运算符
深拷贝需要new运算符,所以这里简单介绍一下new运算符
new int() 初始化
new int [] 分配大小
深拷贝和浅拷贝的认识
浅拷贝就是在拷贝的过程中使新的对象指向了被拷贝对象的内存空间,两者共用一块内存空间,所以析构函数销毁空间的时候会出错。系统默认的拷贝函数以及默认的等号操作符都是浅拷贝。
深拷贝的区别就在于拷贝数据的同时还开辟了一块属于自己的空间。
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass(int a_, char * p_)
{
cout << "调用了构造函数" << endl;
this->a = a_;
this->p = p_;
}
~MyClass()
{
cout << "调用了析构函数" << endl;
}
MyClass(const MyClass & obj)
{
cout << "调用拷贝构造函数" << endl;
this->a = obj.a;
this->p = obj.p;
}
MyClass& operator=(const MyClass & t)
{
cout << "调用了等号运算符" << endl;
this->a = t.a;
this->p = t.p;
return *this; //注意返回值
}
public:
int a;
char * p;
};
int main()
{
//使用浅拷贝的情况
char p[] = "abc";
MyClass class1(12, p);
MyClass class2 = class1;
MyClass class3(class1);
class3 = class2; //这里调用的是等号操作符,注意和调用拷贝构造函数区分
return 0;
}
为什么要有深拷贝的这个概念
因为在程序中可能需要类的成员开辟一块空间(用new),开辟完了,用完了就要销毁,否则就是内存泄漏,那么在这个时候如果还是使用浅拷贝的话就会报错。因为被拷贝对象和拷贝对象所指向的内存空间是同一块,同一块空间不能被销毁两次,所以会报错。
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass(int a_, char * p_)
{
cout << "调用了构造函数" << endl;
this->a = a_;
this->p = new char[sizeof(p_) + 1]; //这里开辟了内存空间
strcpy_s(this->p, sizeof(p_) + 1, p_);
}
~MyClass()
{
cout << "调用了析构函数" << endl;
if (this->p != NULL) //这里销毁了内存空间
{
delete p;
p = NULL;
}
}
MyClass(const MyClass & obj)
{
cout << "调用拷贝构造函数" << endl; //这里使用的是浅拷贝
this->a = obj.a;
this->p = obj.p;
}
MyClass& operator=(const MyClass & t)
{
cout << "调用了等号运算符" << endl;
this->a = t.a;
this->p = t.p;
return *this; //注意返回值
}
public:
int a;
char * p;
};
int main()
{
char p[] = "abc";
MyClass c1(12, p);
MyClass c2 = c1;
return 0;
}
如何进行深拷贝
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass(int a, char * p)
{
this->a = a;
this->b = new char[sizeof(p) + 1];
strcpy_s(this->b, sizeof(p) + 1, p);
cout << "使用了构造函数" << endl;
}
MyClass(MyClass const & obj)
{//这里写出来就可以在结果中看到调用情况
cout << "使用了深拷贝构造函数" << endl;
this->a = obj.a;
if (this->b != NULL)
{
this->b = NULL;
this->b = new char[sizeof(obj.b)];
strcpy_s(this->b, sizeof(obj.b), obj.b);
}
}
~MyClass()
{
cout << "使用了析构函数" << endl;
if (this->b != NULL)
{
delete[] b;
b = NULL;
}
}
private:
int a;
char * b;
};
int main()
{
char p[] = "123";
MyClass obj(1, p);
MyClass obj2 = obj;
return 0;
}