二 Class with pointer members(Class String)
1. 测试代码(使用效果)
int main() { String s1(), String s2("hello"); //构造函数 String s3(s1); //拷贝构造 cout << s3 << endl; s3 = s2; //拷贝赋值 cout << s3 << endl; }
2 Big three(三种特殊函数)
class String { public: String(const char* cstr = 0); String(const String& str); //参数为相同类型对象的引用,拷贝构造 String& operator=(const String& str); //拷贝赋值 ~String() //析构函数 char* get_c_str() const{ return m_data; } private: char* m_data; };
2.1 ctor & dtor(构造与析构)
inline String::String(const char* cstr = 0) { if(cstr){ m_data = new char[strlen(cstr)+1]; strcpy(m_data,cstr); } else{ //未指定长度 m_data = new char[1]; *m_data = ' '; } } inline String::~String() { delete[] m_data; }
2.2 Class with pointer members必须有copy ctor(拷贝构造)和copy op(拷贝赋值)
深拷贝与浅拷贝
深拷贝:
inline String::String(const String& str){ m_data = new char[strlen(str.m_data) + 1]; //直接取得另一个对象的private数据 //可用友元解释 strcpy(m_data, str.m_data); }
拷贝赋值函数:
思路:若右边拷贝到左边,步骤为 清空左边;分配与右边相同空间;完成拷贝。
inline String& String::operator=(const String& str){ if(this == &str){ //检测自我赋值,不仅仅是效率问题 return *this; // 如果不检验的话,可能造成行为未定义,见下图解释 } delete[] m_data; // 清除左边 m_data = new char[ strlen(str.m_data) + 1];//开辟空间 strcpy(m_data, str.m_data); //完成拷贝 return *this }
总结:有指针变量的类,一定要重新其拷贝构造,拷贝赋值和析构函数!