浅拷贝和深拷贝是我们学习C++语法上不可避免的一部分,这里我们要对指针变量和指针所指向的内存空间变量要了解清楚才能意识到这个问题的关键所在
下面就是我们刚开始碰到的问题
#pragma once
#include<iostream>
#include<string>
using namespace std;
class Name1
{
private:
char *p;
int len;
public:
Name1(const char *p)
{
len = strlen(p);
p = new char[len+1];
strcpy(this->p, p);
this->p[len] = '\0';
}
~Name1()
{
if (p != NULL)
{
delete []p;
len = 0;
p = NULL;
}
}
};
//浅拷贝 一跑就DANG 因为是浅拷贝 两个指针变量指向同一块内存空间
//析构的时候 一个对象会把内存给析构 然后第二个对象析构的时候会再析构一次 造成内存出错
void playobj1()
{
Name1 obj1("abcdefg");
Name1 obj2 = obj1; //执行浅拷贝 把指针变量的值拷贝过去 并没有另外开辟一块内存空间
}
int main1()
{
playobj1();
return 0;
}
那么我们该怎么解决呢?
#pragma once
#include<iostream>
#include<string>
using namespace std;
class Name
{
private:
char *p=NULL;
int len;
public:
Name(const char *myp)
{
len = strlen(myp);
p = new char[len+1]; //要多申请一个单位的内存
strcpy(p, myp);
//p[len] = '\0';
}
//手工编写拷贝构造函数 实现深拷贝
Name(const Name& obj)
{
len = obj.len;
p = new char[len + 1];
strcpy(p, obj.p);
}
~Name()
{
if (p != NULL) //析构之前先判断
{
delete[]p;
p = NULL; //注意 这里要让指针指向0 避免野指针的出现
len = 0;
}
}
//重载=操作符
Name& operator=(const Name& obj)
{
if (p != NULL) //同理先判断指针是否为空
{
delete[]p; //先释放 并让他指向NULL
p = NULL;
len = 0;
}
len = obj.len;
p = new char[len + 1]; //在申请 并且进行copy
strcpy(p, obj.p);
return *this;
}
};
void objplay()
{
Name n1("abcdefg");
Name n2 = n1;
Name n3 = ("obj3");
n3 = n1; //此时会DANG机 因为没有重载等号操作符
}
int main02()
{
objplay();
return 0;
}