Class with pointer members(Class String)
1. 測(cè)試代碼(使用效果)
int main()
{
String s1(),
String s2("hello"); //構(gòu)造函數(shù)
String s3(s1); //拷貝構(gòu)造
cout << s3 << endl;
s3 = s2; //拷貝賦值
cout << s3 << endl;
}
2. Big Three 三種特殊函數(shù)
編譯器默認(rèn)的拷貝構(gòu)造和拷貝復(fù)制不適用于包含指針的類,所以要自己寫
class String
{
public:
String(const char* cstr = 0);
String(const String& str); //參數(shù)為相同類型對(duì)象的引用,拷貝構(gòu)造
String& operator=(const String& str); //拷貝賦值
~String() //析構(gòu)函數(shù)
char* get_c_str() const{
return m_data;
}
private:
char* m_data;
};
2.1 ctor & dtor(構(gòu)造與析構(gòu))
inline
String::String(const char* cstr = 0)
{
if(cstr){
m_data = new char[strlen(cstr)+1]; //用new動(dòng)態(tài)分配大小
strcpy(m_data,cstr);
}
else{ //未指定長(zhǎng)度
m_data = new char[1];
*m_data = '\0';
}
}
inline
String::~String()
{
delete[] m_data;
}
2.2 Class with pointer members必須有copy ctor(拷貝構(gòu)造)和copy op(拷貝賦值)
淺拷貝
深拷貝
inline
String::String(const String& str){
m_data = new char[strlen(str.m_data) + 1]; //直接取得另一個(gè)對(duì)象的private數(shù)據(jù)
//可用友元解釋
strcpy(m_data, str.m_data);
}
拷貝賦值函數(shù)
思路:若右邊拷貝到左邊冕屯,步驟為 清空左邊;分配與右邊相同空間强戴;完成拷貝赠堵。
inline
String& String::operator=(const String& str){
if(this == &str){ //檢測(cè)自我賦值医清,不僅僅是效率問題
return *this; // 如果不檢驗(yàn)的話量蕊,可能造成行為未定義铺罢,見下圖解釋
}
delete[] m_data; // 清除左邊
m_data = new char[ strlen(str.m_data) + 1];//開辟空間
strcpy(m_data, str.m_data); //完成拷貝
return *this
}
3. 重載<<操作符
按照通常的用法,cout<<s残炮,所以不能重載為成員函數(shù)(要不然使用不便)韭赘,就用全局重載好了
ostream& operator<<(ostream& os, const String str)
{
os << str.get_c_str();
return os;
}
總結(jié):有指針變量的類,一定要重新其拷貝構(gòu)造势就,拷貝賦值和析構(gòu)函數(shù)泉瞻!