1、構造函數和析構函數
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <iostream> 3 #include<cstdlib> 4 5 using namespace std; 6 7 class Test { 8 public: 9 Test() { 10 11 } 12 Test(int x, int y) { 13 m_x = x; 14 m_y = y; 15 name = (char*)malloc(100); 16 strcpy(name, "zhang3"); 17 //此時在堆上開辟了空間,Test對象相關的函數都執行完后會自行銷毀(棧上空間) 18 //但是堆上的空間就變成了垃圾 19 //造成內存泄露,需要析構函數來完成釋放堆上空間 20 } 21 ~Test() { 22 cout << "~Test()" << endl; 23 if (name != NULL) { 24 free(name); 25 cout << "free succ" << endl; 26 } 27 } 28 void print_t() { 29 cout << "x=" << m_x << ",y=" << m_y << endl; 30 } 31 private: 32 int m_x; 33 int m_y; 34 char *name; 35 }; 36 37 void test1() { 38 Test t1(10, 20); 39 t1.print_t(); 40 } 41 int main(void) { 42 test1(); 43 system("pause"); 44 return 0; 45 }
2、拷貝構造函數
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <iostream> 3 #include<cstdlib> 4 5 using namespace std; 6 7 class Test { 8 public: 9 //顯示無參構造、顯示有參構造、顯示拷貝構造都會使默認的無參構造函數無效 10 //默認的無參構造函數屬性值隨機分配,所以如果需要無參構造函數,還是需要自定義一個 11 Test() { 12 m_x = 0; 13 m_y = 0; 14 } 15 Test(int x, int y) { 16 m_x = x; 17 m_y = y; 18 } 19 ~Test() { 20 cout << "~Test()" << endl; 21 } 22 void print_t() { 23 cout << "x=" << m_x << ",y=" << m_y << endl; 24 } 25 #if 0 26 //拷貝構造函數的顯示形式,const修飾是為了保護參數 27 Test(const Test &another) { 28 m_x = another.m_x; 29 m_y = another.m_y; 30 } 31 //=等號操作符重載 32 void operator=(const Test &another) { 33 m_x = another.m_x; 34 m_y = another.m_y; 35 } 36 #endif 37 38 private: 39 int m_x; 40 int m_y; 41 }; 42 43 int main(void) { 44 Test t1(100, 200); 45 Test t2(t1);//調用默認的拷貝構造函數 46 t2.print_t(); 47 48 Test t3 = t1;//初始化t3時調用t3的拷貝構造函數 49 Test t4; 50 t4 = t1;//此時調用的不是拷貝構造函數,而是賦值操作符重載函數 51 system("pause"); 52 return 0; 53 }
3、 應用場景
對象作為形參,傳值時也是調用拷貝構造函數,下圖中,當調用func(t1)時,實際上是Test t = t1,這是一個拷貝構造函數調用。

3.1 如果函數返回值是用一個對象接收的,那么會發生一個值拷貝,通過拷貝構造函數創建一個匿名對象。如下有函數Test func2(){ }:

3.2 如果返回值有一個對象來接收,那么這個接收過程不會出發值拷貝。

3.3 另一種更為復雜的情況,等號操作符重載:

