如果一个类中包含指针,通常拷贝和赋值都要重新写
#include<iostream>
#include <cstring>
using namespace std;
class String
{
private:
char* data;
public:
String(const char* ArgData = NULL);
String(const String& Str);
const String& operator=(const String& Str);
~String();
};
String::String(const char* ArgData)
{
if(ArgData==NULL)
{
this->data = NULL;
}
else
{
this->data= new char[strlen(ArgData)+1];
strcpy(this->data,ArgData);
}
}
String::String(const String& Str)
{
if(Str.data==NULL)//如果Str.data是指向空地址,直接给新对象赋值空地址
{//否则strlen函数参数如果是NULL,则会出错,标准C库的字符串处理函数 strxxx 一系列函数中,对参数传入NULL会导致程序崩溃
this->data = NULL;
}
else
{//ctrcpy(str1,str2),判断str2结束的标志是'/0',如果str2是NULL则会一直拷贝,程序奔溃
this->data = new char[strlen(Str.data)+1];//开辟空间,+1是因为 strlen() 不把字符串结尾'/0'算作有效字符
strcpy(this->data,Str.data);//strcpy() 函数会拷贝字符串结束符'/0'
}
}
const String& String::operator=(const String& Str)
{
if(this != &Str)//避免自己给自己复制,浪费时间
{
if(Str.data==NULL)
{
this->data = NULL;
}
else
{
delete[] this->data;//释放掉原来已经开辟的空间
this->data = NULL;//如果内存申请不成功,我要保证代码安全
this->data = new char[strlen(Str.data)+1];
strcpy(this->data,Str.data);
}
}
return *this;
}
String::~String()
{
if(this->data != NULL)//1.这个对象的data从没有赋值过,2.如果程序中有人修改的data = NULL,很明显NULL是不能释放的
{
delete[] this->data;
this->data = NULL;
}
}
/*更正NULL是不能释放的!
面试某公司的时候,某技术主管说你这delete前没有判断指针是否为NULL,当时我就……
看来这是个传说中的好习惯,每当delete一个指针的时候,要先判断是不是NULL。比如:
if ( p != NULL)
delete p; //释放掉p指向的内存后,一定要立马给p赋值,否则变成野指针,不然别的程序用到的p的时候很危险
p = NULL;
C++标准规定,delete (void*)0;是安全的。
二现在的编译器通常都会有一个#define NULL 0的宏
所以,delete NULL也是安全的,是一个空操作;
另外,我们真正需要在delete时做的事情是:在delete后,将该指针赋值为NULL,防止多次delete该指针。
*/
int main()
{
String s1("hello world");
String s2(s1);
s1 = s2;
return 0;
}