在学习c语言和c++编程的过程中很多时候都会很困惑觉得这个东西也就那么点语法,学完了之后好像就可以干一些大事情了,但是大事情没有完成,对语言的学习确有一点止步了,还是感觉学到头了,很多东西虽然用得不怎么熟练但是看看就知道了,今天看了本新的书,又尝试了一些原来没有用过的东西,发现在编写程序和调试程序的方面还有很多的东西要学,以下面的程序为例(一些改动都在注释里面),写了两个不同的复制操作符函数,但是同样的代码函数与不同的其他函数搭配时确导致程序崩溃,而这些问题使用简单的debug也难以找到问题的原因,需要会查看Stack监视窗口和程序翻译的反汇编语言窗口(vc ++ 6.0中是view下面的disassembly),而且在disassembly程序中也可以断点执行程序,只有通过这样的细节才能找到真正的原因,原因我基本上都用注释写在程序中了,下面贴出代码,最好能亲手运行并调试一下,肯定收获颇多。
#include <iostream>
class CMyString
{
public:
CMyString(char * pData = NULL);
CMyString(const CMyString &str);
~CMyString(void);
CMyString & operator = (const CMyString &str);
void Print() const;
private:
char *m_pData;
};
CMyString::CMyString(char *pData )
{
this ->m_pData = pData;
}
//反复使用这个函数导致栈溢出
CMyString::CMyString(const CMyString &str)
{
if(this != &str)
{
// CMyString strTemp(str); //这个语句的会无限制跳转回该构造函数
//在复制构造函数中不能也使用函数复制的语句,否则会无限递归导致栈溢出
char *pTemp;
pTemp = str.m_pData;
// strTemp.m_pData = m_pData;
m_pData = pTemp;
}
/*
这个代码是在已经注释的函数时使用的,没有任何问题,但是在重写的复制操作符
时,会导致程序死掉,原因就是这个函数和复制函数的反复相互调用,导致栈溢出
*/
//*this = str;
}
CMyString::~CMyString(void)
{
}
/*
如果不使用引用编译没有问题,运行是会出现问题,
调试会发现使用一个等号,主函数栈中会调用两次operation = 函数
我猜测第一次使用是等号运算,第二次调用是返回值是因为不是引用
直接返回String使用的CMyString是复制实例,需要调用一次复制构
造函数,而在构造函数里面又有一个operator = 操作,需要调用一
次operator = 函数,
可以在调试的窗口里面找到Stack,查看调用的函数顺序,通过监控
具体的函数的汇编代码(可以断点调试),可以找到函数每一步的细
节从而查看函数运行情况
*/
/*
CMyString & CMyString::operator = (const CMyString &str)
{
if(this == &str)
return *this;
delete []m_pData;
m_pData = new char(strlen(str.m_pData)+1);
strcpy(m_pData,str.m_pData);
return *this;
}
*/
CMyString & CMyString::operator = (const CMyString &str)
{
if(this != &str)
{
CMyString strTemp(str);
char *pTemp = strTemp.m_pData;
strTemp.m_pData = m_pData;
m_pData = pTemp;
}
return *this;
}
void CMyString::Print() const
{
std::cout<<m_pData<<std::endl;
}
int main()
{
CMyString s1("hahaha");
s1.Print();
CMyString s2;
CMyString s3;
s3=s2=s1;
s3.Print();
s2=s1;
s2.Print();
return 0;
}