手敲实现了一下书中的CMyString类,发现有几个需要注意的点:
- 要注意指针参数可能为空,即空指针的情况,其在实际运行时会引发异常。
- cout不能输出空指针指向的内容,strcpy的参数必须是非空指针,否则会有异常
- 在赋值运算符重载时,应该注意:形参类型是常引用;返回值应为对象的引用,以保证“=”可以连等的写法(这个类似于<<与iostream的实现);在new新的空间写新内容之前,需要先将之前的内存delete;同时要特判"t=t"的情况,防止将自身delete.
代码如下:
#include <iostream>
using namespace std;
class Cstring {
private:
char* m_str; //m_str有指向自身实例独有的字符串存放内存
public:
Cstring(char* p = NULL);
Cstring(const Cstring& str);
~Cstring(void);
Cstring& operator = (const Cstring& str);
void print() {
if(m_str!=NULL)
cout << "Str:\t" << m_str << endl;
}
};
Cstring::Cstring(char* p)
{
if (p == NULL)
{
m_str = NULL;
return;
}
m_str = new char[strlen(p)]; //对一个空指针NULL strlen会引发异常
if (m_str != NULL)
strcpy(m_str, p);
}
//深复制 此处不能是浅复制,否则指向同一块内存,另一对象的析构产生“野指针”
Cstring::Cstring(const Cstring& str)
{
unsigned int i = strlen(str.m_str);
m_str = new char[i];
if (m_str != NULL)
strcpy(m_str, str.m_str);
}
Cstring::~Cstring(void)
{
delete[] m_str;
m_str = NULL; //指针需要赋空
}
Cstring& Cstring:: operator = (const Cstring& str)
{
if (&str == this)
return *this;
delete[] m_str;
m_str = NULL;
m_str = new char[strlen(str.m_str)];
if (m_str != NULL)
strcpy(m_str, str.m_str);
return *this;
}
int main()
{
char p[] = "myFirstStirngClass";
Cstring str1(p);
Cstring str2 = str1;
Cstring str3;
str1.print();
str2.print();
str3.print();
str3 = str2 = str1;
str1.print();
str2.print();
str3.print();
//while (1) getchar();
return 0;
}