一,關於構造函數
作用:初始化類的成員變量,所以當創建類對象或者類對象被創建就會調用構造函數。
特點:
- 函數名和類名一樣,且沒有返回值
- 當沒有顯式的定義構造函數時,系統會自己生成默認的構造函數
- 構造函數可以重載
二,構造函數的幾種表現形式
2.1 默認的構造函數
Test1.cpp
1 #include "test1.h" 2 3 Test1::Test1() 4 { 5 cout<< "Test1 construction" << endl; 6 } 7 8 Test1::~Test1() 9 { 10 cout<< "~Test1 destructor" << endl; 11 } 12 13 void Test1::getInfo() 14 { 15 cout << "get: year: " << m_year << " month: " << m_month << " day: " << m_day << endl; 16 }
Test1.h
#ifndef TEST1_H #define TEST1_H #include <iostream> using namespace std; class Test1 { public: Test1();//默認構造函數 ~Test1();//析構函數 void getInfo(); private: int m_year; int m_month; int m_day; }; #endif // TEST1_H
2.2 自定義的構造函數
Test2.cpp
1 /* 2 * Test2 3 */ 4 Test2::Test2() 5 { 6 cout<< "Test2 default construction" << endl; 7 } 8 Test2::Test2(int year, int month, int day) 9 { 10 m_year = year; 11 m_month = month; 12 m_day = day; 13 cout<< "Test2 construction" << endl; 14 } 15 16 Test2::~Test2() 17 { 18 cout<< "~Test2 destructor" << endl; 19 } 20 21 void Test2::getInfo() 22 { 23 cout << "get: year: " << m_year << " month: " << m_month << " day: " << m_day << endl; 24 }
Test2.h
1 class Test2 2 { 3 public: 4 Test2();//默認構造函數 5 Test2(int year=19, int month=4, int day=15);//帶有默認參數的構造函數 6 ~Test2();//析構函數 7 void getInfo(); 8 private: 9 int m_year; 10 int m_month; 11 int m_day; 12 };
注意事項:
注意使用默認參數時,有可能出現重復定義的構造函數
1 //測試用例1 2 Test2 t21;//錯誤的使用,重復的構建函數 3 t21.getInfo(); 4 5 //錯誤信息 6 /* 7 D:\QT_project\test\Test\main.cpp:21: error: C2668: 'Test2::Test2' : ambiguous call to overloaded function 8 d:\qt_project\test\test\test1.h(23): could be 'Test2::Test2(int,int,int)' 9 d:\qt_project\test\test\test1.h(22): or 'Test2::Test2(void)' 10 while trying to match the argument list '()' 11 */ 12 13 //測試用例2 14 Test2 t22(1,2);//正確的用法 15 t22.getInfo();
2.3 初始化列表
注意事項1:
初始化列表的賦值時刻和函數體內賦值是不同的,初始化列表是在對象創建成功之前完成的,而函數體內賦值是在對象成員創建成功后進行賦值操作。
必須使用初始化列表的幾種場景:
- 成員是const類型或者是引用類型
- 有一個成員是類類型的對象(且沒有缺省的構造函數)
Test3.cpp
1 /* 2 * Test3 3 */ 4 5 Test3::~Test3() 6 { 7 cout<< "~Test3 destructor" << endl; 8 } 9 10 void Test3::getInfo() 11 { 12 cout << "get: year: " << m_year << " month: " << m_month << " day: " << m_day << endl; 13 }
Test3.h
1 class Test3 2 { 3 public: 4 //Test3();//默認構造函數 當前成員變量有const類型,且沒有初始化,因此無法使用默認的構造函數 5 Test3(int year, int month, int day) 6 :m_year(year),m_month(month),m_day(day)//初始化列表 7 {} 8 Test3(int year=19, int month=4); 9 ~Test3();//析構函數 10 void getInfo(); 11 private: 12 int m_year; 13 int m_month; 14 int const m_day; 15 };
main.cpp
1 Test3 t3(19,4,15); 2 t3.getInfo();
關於1,因為對於const和引用類型必須要進行初始化,所以必須在初始化列表中進行初始化
關於2,當類類型成員有缺省的構造函數時,在創建對象的時候系統會默認調用,因為不用傳參。但是當你的構造函數不是缺省的,如果不在初始化列表中進行調用構造函數,系統就無法知道怎么調用類類型成員的構造函數,那么就無法創建。
1 class Time 2 { 3 public: 4 Time(int h) 5 { 6 m_hour = h; 7 } 8 private: 9 int m_hour; 10 }; 11 12 class Test3 13 { 14 public: 15 Test3(int year, int month, int day) 16 :m_year(year),m_month(month),m_day(day), t(10)//初始化列表 17 {} 18 ~Test3();//析構函數 19 void getInfo(); 20 private: 21 int m_year; 22 int m_month; 23 int const m_day; 24 Time t; 25 };
注意事項2:
成員初始化順序:初始化列表的順序並不限定初始化的執行循序。成員的初始化順序是與類中定義的的順序保持一致。
<文檔結束>