#include <iostream>
#include<cstring>
using namespace std;
class MyString
{
char *buff;
public:
MyString(const char *Input)
{
if (Input != NULL)
{
buff = new char[strlen(Input) + 1];
strcpy(buff, Input);
}
else
buff = NULL;
}
~MyString()
{
delete[] buff;
}
int GetLegth()
{
return strlen(buff);
}
const char *GetBuff()
{
return buff;
}
};
void ShowMystring(MyString s)
{
cout << "String's length is: " << s.GetLegth() << endl;
cout << "String is :" << s.GetBuff();
}
int main(int argc, char **argv)
{
MyString ms("HELLO!");
ShowMystring(ms);
system("pause");
}
这段程序会报错
原因就是在main函数中传递了MyString的对象到ShowMystring函数中,这里采用的就是浅复制。
因为是 按值传递的参数,所以将对象进行传递,编译器进行二次复制,只会复制其指针成员,而不复制指针指向的缓冲区域,导致其指针成员指向同一个地址。
在函数执行完毕之后,传入的对象s,就脱离了其作用域,就要执行其析构函数,delete []buff,是针对于构造函数中的new来使用的。然后函数返回到主函数中,执行完毕后,ms也要释放其空间,但是已经被释放了,调用其析构函数,进行delete[]buff,就会报错。
如何能解决上面的错误:就是采用定义拷贝构造函数来进行深复制
#include <iostream>
#include<cstring>
using namespace std;
class MyString
{
char *buff;
public:
MyString(const MyString& ms)
{//拷贝构造函数
if(ms.buff!=NULL)
{
buff = new char[strlen(ms.buff)+1];
strcpy(buff,ms.buff);
}
else
buff = NULL;
}
MyString(const char *Input)
{
if (Input != NULL)
{
buff = new char[strlen(Input) + 1];
strcpy(buff, Input);
}
else
buff = NULL;
}
~MyString()
{
delete[] buff;
}
int GetLegth()
{
return strlen(buff);
}
const char *GetBuff()
{
return buff;
}
};
void ShowMystring(MyString s)
{
cout << "String's length is: " << s.GetLegth() << endl;
cout << "String is :" << s.GetBuff();
}
int main(int argc, char **argv)
{
MyString ms("HELLO!");
ShowMystring(ms);
system("pause");
}
加上拷贝构造函数。
当调用函数时,传递参数,会默认调用对象的拷贝构造函数,这不仅仅复制其指针的,而且还会复制其缓冲区,指向新的地址,这样当函数调用完毕后不会影响main函数中的对象
图来自21天学通c++