对象的初始化和清理
對象的初始化和清理
構造函數和析構函數
對象的初始化和清理也是兩個非常重要的安全問題
? 一個對象或者變量沒有初始狀態,對其使用后果是未知
? 同樣的使用完一個對象或變量,沒有及時清理,也會造成一定的安全問題
c++利用了構造函數和析構函數解決上述問題,這兩個函數將會被編譯器自動調用,完成對象初始化和清理工作。
對象的初始化和清理工作是編譯器強制要我們做的事情,因此如果我們不提供構造和析構,編譯器會提供編譯器提供的構造函數和析構函數是空實現。
-
構造函數:主要作用在于創建對象時為對象的成員屬性賦值,構造函數由編譯器自動調用,無須手動調用
-
析構函數:主要作用在于對象銷毀前系統自動調用,執行一些清理工作。
構造函數語法:類名(){}
構造函數,沒有返回值也不寫void
函數名稱與類名相同
構造函數可以有參數,因此可以發生重載
程序在調用對象時候會自動調用構造,無須手動調用,而且只會調用一次
析構函數語法: ~類名(){}
析構函數,沒有返回值也不寫void
函數名稱與類名相同,在名稱前加上符號 ~
析構函數不可以有參數,因此不可以發生重載
程序在對象銷毀前會自動調用析構,無須手動調用,而且只會調用一次
構造函數的分類及調用
兩種分類方式:
? 按參數分為: 有參構造和無參構造
? 按類型分為: 普通構造和拷貝構造
三種調用方式:
? 括號法
? 顯示法
? 隱式轉換法
#include <iostream> using namespace std;//1、構造函數分類 // 按照參數分類分為 有參和無參構造 無參又稱為默認構造函數 // 按照類型分類分為 普通構造和拷貝構造class Person { public://無參(默認)構造函數Person() {cout << "無參構造函數!" << endl;}//有參構造函數Person(int a) {age = a;cout << "有參構造函數!" << endl;}//拷貝構造函數Person(const Person& p) {age = p.age;cout << "拷貝構造函數!" << endl;}//析構函數~Person() {cout << "析構函數!" << endl;} public:int age; };//2、構造函數的調用 //調用無參構造函數 void test01() {Person p; //調用無參構造函數 }//調用有參的構造函數 void test02() {//2.1 括號法,常用Person p1(10);//注意1:調用無參構造函數不能加括號,如果加了編譯器認為這是一個函數聲明//Person p2();//2.2 顯式法Person p2 = Person(10); Person p3 = Person(p2);//Person(10)單獨寫就是匿名對象 當前行結束之后,馬上析構//2.3 隱式轉換法Person p4 = 10; // Person p4 = Person(10); Person p5 = p4; // Person p5 = Person(p4); //注意2:不能利用 拷貝構造函數 初始化匿名對象 編譯器認為是對象聲明//Person p5(p4); }int main() {//test01();test02();system("pause");return 0; }拷貝構造函數調用時機
C++中拷貝構造函數調用時機通常有三種情況
-
使用一個已經創建完畢的對象來初始化一個新對象
-
值傳遞的方式給函數參數傳值
-
以值方式返回局部對象
test01();運行結果
test02();運行結果
test03();運行結果
構造函數調用規則
默認情況下,c++編譯器至少給一個類添加3個函數
1.默認構造函數(無參,函數體為空)
2.默認析構函數(無參,函數體為空)
3.默認拷貝構造函數,對屬性進行值拷貝
構造函數調用規則如下:
-
如果用戶定義有參構造函數,c++不在提供默認無參構造,但是會提供默認拷貝構造
-
如果用戶定義拷貝構造函數,c++不會再提供其他構造函數
總結
- 上一篇: 结构体案例
- 下一篇: 初始化列表||类对象作为类成员|| 静态