C++類中的成員函數的三大件(Big Three):拷貝構造函數,賦值運算符重載函數,析構函數。
拷貝構造函數:用已存在類對象賦值給將要創建對象賦值,創建出新的對象。
一般定義如下:
String(const String&);//參數中的引用不能去掉,否則造成死循環。
賦值運算符重載函數:一般定義爲類的成員函數,當類中有指針變量時,通常分四步走,判斷是否是自賦值;是的話刪除舊空間;創建新空間;用strcpy進行賦值;最終返回*this。
一般定義如下:
const String& operator=(const String&);
析構函數:當對象離開其作用域時,調用析構函數,用於銷燬對象釋放空間。
一般定義如下:
~String();
爲什麼要用三大件?主要是爲了實現深拷貝。
具體代碼如下:
// // String.h // BigThree // // Created by student on 15/8/14. // Copyright (c) 2015年 personals. All rights reserved. // #ifndef __BigThree__String__ #define __BigThree__String__ #include <iostream> #include <string> using namespace std; class String{ public: String(const char *str = ""); // 通用構造函數 String(const String &another); // 拷貝構造函數 ~String(); // 析構函數 const String& operator =(const String& rhs); // 賦值函數 friend ostream& operator<<(ostream& os,const String& s); // 輸出運算符重載; private: char* m_data; // 用於保存字符串 }; #endif /* defined(__BigThree__String__) */
// // String.cpp // BigThree // // Created by student on 15/8/14. // Copyright (c) 2015年 personals. All rights reserved. // #include "String.h" String::String (const char *str){ if (!str) { m_data = NULL; } else{ m_data = new char[strlen(str)+1]; strcpy(m_data,str); } cout<<"Constructor is called!\n"; } String::String (const String &another){ if(!another.m_data){ m_data = NULL; } else{ m_data = new char[strlen(another.m_data)+1]; strcpy(m_data,another.m_data); } cout<<"Copy constructor is called!\n"; } String::~String(){ if (m_data!=NULL) { delete [] m_data; } cout<<"Destructor is called!\n"; } const String& String::operator =(const String &rhs){ if(this != &rhs){ // >1判斷是否是自賦值; delete [] m_data; // >2 刪除舊空間; if(!rhs.m_data){ m_data = NULL; } else{ m_data = new char[strlen(rhs.m_data)+1]; // >3創建新空間,並實現內容拷貝; strcpy(m_data,rhs.m_data); } } cout<<"Assignment operator overloading function is called!\n"; return *this; // >4返回*this,方便鏈式調用; } ostream& operator<<(ostream& os,const String& s){ os<<"string is:"<<s.m_data<<endl; return os; }
// // main.cpp // BigThree // // Created by student on 15/8/14. // Copyright (c) 2015年 personals. All rights reserved. // #include <iostream> #include "String.h" int main(int argc, const char * argv[]) { // insert code here... String s1,s2("asdf"); //調用兩次構造函數; s1 = s2; //調用賦值運算符重載; cout<<"s1 "<<s1<<"s2 "<<s2; String s3=s2; //調用拷貝構造函數(或者String s3(s2)); cout<<"s3 "<<s3; //std::cout << "Hello, World!\n"; return 0; //最終調用調用三次析構函數,先析構拷貝構造再析構構造函數; }
輸出結果:
Constructor is called!
Constructor is called!
Assignment operator overloading function is called!
s1 string is:asdf
s2 string is:asdf
Copy constructor is called!
s3 string is:asdf
Destructor is called!
Destructor is called!
Destructor is called!
Program ended with exit code: 0