#include <string.h>
#include<iostream.h>
//自定义字符串类
class CString
{
public:
CString(char *pSrc);
//CString(const CString & Src);
~CString();
public:
char *m_pData;
};
CString::CString(char *pSrc)
{
m_pData = new char [256];
strcpy(m_pData, pSrc);
cout<<"Constructing:"<<m_pData<<endl;
}
/*
CString::CString(const CString &Src)
{
m_pData = new char [256];
strcpy(m_pData, Src.m_pData);
cout<<"Copy Constructing:"<<m_pData<<endl;
}*/
CString::~CString()
{
cout<<"Destroying:"<<m_pData<<endl;
if(m_pData)
{
delete [] m_pData;
m_pData = NULL;
}
}
void foo(CString m)
{
//什么都没干,但注定要闯祸
}
void main()
{
CString s("yahoo!");
foo(s);
cout<<s.m_pData<<endl;
}
是析构函数捣的鬼。
当调用foo()时,C++将s对象完全拷贝了一份作为参数(即临时对象m,注意m.m_pData == s.m_pData,没有谁会为m.m_pData再申请一份内存)传送过去,而在结束foo()函数之前,C++将会调用析构函数销毁掉临时对象m,~CString()释放了m.m_pData指向的内存(也即s.m_pData苦心经营的那份内存),当s对象再来取值的时候,咣当!悲剧发生了。看来,析构不是什么好玩的东西,为了避免析构产生不必要的麻烦,以下是一些程序员最好做的:
对于内存动态分配的类,定义其拷贝构造函数(copy constructor)。
----<<白乔原创:艺术编程之C++篇[3]>>
我的解释:void foo(CString m)的参数传递是值传递,没有调用构造函数,但撤消时调用了析构函数,这样一个指针被删了两次,所以出错。
疑问:拷贝构造函数什么情况下被调用?