C++語(yǔ)法詳解之封裝、構(gòu)造函數(shù)、析構(gòu)函數(shù)
大家先了解下什么是構(gòu)造函數(shù),什么是析構(gòu)函數(shù),作用是什么?
構(gòu)造函數(shù)(方法)是對(duì)象創(chuàng)建完成后第一個(gè)被對(duì)象自動(dòng)調(diào)用的方法。它存在于每個(gè)聲明的類中,是一個(gè)特殊的成員方法。作用是執(zhí)行一些初始化的任務(wù)。Php中使用__construct()聲明構(gòu)造方法,并且只能聲明一個(gè)。
析構(gòu)函數(shù)(方法)作用和構(gòu)造方法正好相反,是對(duì)象被銷毀之前最后一個(gè)被對(duì)象自動(dòng)調(diào)用的方法。是PHP5中新添加的內(nèi)容作用是用于實(shí)現(xiàn)在銷毀一個(gè)對(duì)象之前執(zhí)行一些特定的操作,諸如關(guān)閉文件和釋放內(nèi)存等。
下面在通過(guò)具體例子看下C++語(yǔ)法詳解之封裝、構(gòu)造函數(shù)、析構(gòu)函數(shù)。
成員變量私有化,提供公共的getter和setter給外界去訪問(wèn)成員變量
class Person {
int age;
public:
void setAge(int age){
this->age = age;
}
int getAge(){
return this->age;
}
};
int main(){
Person person;
person.setAge(10);
cout << person.getAge() << endl;
}
堆空間
在程序運(yùn)行過(guò)程,為了能夠自由控制內(nèi)存的生命周期、大小,會(huì)經(jīng)常使用堆空間的內(nèi)存
堆空間的申請(qǐng)\釋放
malloc \ free
new \ delete
new [] \ delete []
注意
- 申請(qǐng)堆空間成功后,會(huì)返回那一段內(nèi)存空間的地址
- 申請(qǐng)和釋放必須是1對(duì)1的關(guān)系,不然可能會(huì)存在內(nèi)存泄露
現(xiàn)在的很多高級(jí)編程語(yǔ)言不需要開發(fā)人員去管理內(nèi)存(比如Java),屏蔽了很多內(nèi)存細(xì)節(jié),利弊同時(shí)存在
- 利:提高開發(fā)效率,避免內(nèi)存使用不當(dāng)或泄露
- 弊:不利于開發(fā)人員了解本質(zhì),永遠(yuǎn)停留在API調(diào)用和表層語(yǔ)法糖,對(duì)性能優(yōu)化無(wú)從下手
例如開盤int類型的空間,使用完之后銷毀
int *p = (int *)malloc(sizeof(int)); *p = 10; free(p); int *p2 = new int; *p2 = 20; delete p2; int *p3 = new int[3]; *p = 10; *(p+1) = 20; *(p+2) = 30; delete [] (p3);
堆空間的初始化
memset
memset 函數(shù)是將較大的數(shù)據(jù)結(jié)構(gòu)(比如對(duì)象、數(shù)組等)內(nèi)存清零的比較快的方法
如下所示
Person person; person.age = 10; person.height = 199; //從person的地址開始,每個(gè)字節(jié)都賦值為0 memset(&person, 0, sizeof(person));
初始化
int *p1 = (int *)malloc(sizeof(int)); //*p1 未初始化 int *p2 = (int *)malloc(sizeof(int)); memset(p2, 0, sizeof(int));//將 *p2 的每一個(gè)字節(jié)都初始化為0
如下幾種方式
int *p1 = new int; //未初始化
int *p2 = new int(); //被初始化為0
int *p3 = new int(5); //被初始化為5
int *p4 = new int[3]; //數(shù)組元素未被初始化
int *p5 = new int[3](); //3個(gè)數(shù)組元素都被初始化0
int *p6 = new int[3]{}; //3個(gè)數(shù)組元素都被初始化0
int *p7 = new int[3]{5}; //數(shù)組首元素被初始化為5,其他元素被初始化為0
構(gòu)造函數(shù)(Constructor)
構(gòu)造函數(shù)(也叫構(gòu)造器),在對(duì)象創(chuàng)建的時(shí)候自動(dòng)調(diào)用,一般用于完成對(duì)象的初始化工作
特點(diǎn)
- 函數(shù)名與類同名,無(wú)返回值(void都不能寫),可以有參數(shù),可以重載,可以有多個(gè)構(gòu)造函數(shù)
- 一旦自定義了構(gòu)造函數(shù),必須用其中一個(gè)自定義的構(gòu)造函數(shù)來(lái)初始化對(duì)象
注意
通過(guò)malloc分配的對(duì)象不會(huì)調(diào)用構(gòu)造函數(shù)
一個(gè)廣為流傳的、很多教程\書籍都推崇的錯(cuò)誤結(jié)論:
默認(rèn)情況下,編譯器會(huì)為每一個(gè)類生成空的無(wú)參的構(gòu)造函數(shù)
正確理解:在某些特定的情況下,編譯器才會(huì)為類生成空的無(wú)參的構(gòu)造函數(shù)
比如我們自己寫2個(gè)構(gòu)造函數(shù)
class Person{
public:
int age;
Person(){
cout << "Person()" << endl;
}
Person(int age){
cout << "Person(int age))" << endl;
}
};
在不同的空間調(diào)用的時(shí)候,如下區(qū)別
// 全局區(qū)
Person p1; //調(diào)用Person()
Person p2(); //這是一個(gè)函數(shù),函數(shù)名是p2,返回值類型是Person,無(wú)參
Person p3(18); //調(diào)用 Person(int)
int main(){
//??臻g
Person p4; //調(diào)用Person()
Person p5(); //這是一個(gè)函數(shù),函數(shù)名是p5,返回值類型是Person,無(wú)參
Person p6(18); //調(diào)用 Person(int)
//堆空間
Person *p7 = new Person; //調(diào)用Person()
Person *p8 = new Person(); //調(diào)用Person()
Person *p9 = new Person(20); //調(diào)用 Person(int)
}
析構(gòu)函數(shù)
析構(gòu)函數(shù)(也叫析構(gòu)器),在對(duì)象銷毀的時(shí)候自動(dòng)調(diào)用,一般用于完成對(duì)象的清理工作
特點(diǎn)
函數(shù)名以~開頭,與類同名,無(wú)返回值(void都不能寫),無(wú)參,不可以重載,有且只有一個(gè)析構(gòu)函數(shù)
注意
- 通過(guò)malloc分配的對(duì)象free的時(shí)候不會(huì)調(diào)用析構(gòu)函數(shù)
- 構(gòu)造函數(shù)、析構(gòu)函數(shù)要聲明為public,才能被外界正常使用
例如下面的代碼
class Cat{
public:
int age;
Cat(){
cout << "Cat()" << endl;
}
~Cat(){
cout << "~Cat()" << endl;
}
};
class Person{
public:
int age;
Cat *cat;
Person(){
this->cat = new Cat();
cout << "Person()" << endl;
}
~Person(){
cout << "~Person()" << endl;
}
};
int main(){
{
Person person;
}
return 0;
}
輸出
Cat()
Person()
~Person()
當(dāng)person銷毀的時(shí)候,其持有的cat并沒(méi)有銷毀。
原因
當(dāng)person銷毀的時(shí)候,其指向cat對(duì)象的指針銷毀了,但是堆空間的cat對(duì)象依然存在,就會(huì)有內(nèi)存泄露。所以需要在析構(gòu)函數(shù)里面來(lái)釋放掉。類似的析構(gòu)函數(shù)在許多其他語(yǔ)言底層也是應(yīng)用廣泛,例如Objective-C的源碼中,大量使用析構(gòu)函數(shù)。
代碼改成如下所示:
~Person(){
delete cat;
cout << "~Person()" << endl;
}
輸出
Cat()
Person()
~Cat()
~Person()
可知,cat對(duì)象才真正銷毀。
總結(jié)
到此這篇關(guān)于C++語(yǔ)法詳解之封裝、構(gòu)造函數(shù)、析構(gòu)函數(shù)的文章就介紹到這了,更多相關(guān)c++ 封裝構(gòu)造函數(shù)析構(gòu)函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++超詳細(xì)講解構(gòu)造函數(shù)與析構(gòu)函數(shù)的用法及實(shí)現(xiàn)
- C++編程析構(gòu)函數(shù)拷貝構(gòu)造函數(shù)使用示例詳解
- C++中構(gòu)造函數(shù)與析構(gòu)函數(shù)的詳解及其作用介紹
- C++:構(gòu)造函數(shù),析構(gòu)函數(shù)詳解
- 正確理解C++的構(gòu)造函數(shù)和析構(gòu)函數(shù)
- c++ 入門——淺析構(gòu)造函數(shù)和析構(gòu)函數(shù)
- C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用與講解
- C++中構(gòu)造函數(shù)與析構(gòu)函數(shù)的調(diào)用順序詳解
- C++類與對(duì)象深入之構(gòu)造函數(shù)與析構(gòu)函數(shù)詳解
相關(guān)文章
Visual Studio 2022無(wú)法打開源文件的解決方式
這篇文章主要介紹了Visual Studio 2022無(wú)法打開源文件的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
數(shù)據(jù)結(jié)構(gòu)順序表操作示例
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)順序表操作示例,其中有在第I個(gè)元素前插入數(shù)據(jù)x,元素從0開始計(jì)數(shù)、刪除第i個(gè)元素,元素從0開始計(jì)數(shù)的方法,需要的朋友可以參考下2014-03-03
C++11 線程同步接口std::condition_variable和std::future的簡(jiǎn)單使用示例詳
本文介紹了std::condition_variable和std::future在C++中的應(yīng)用,用于線程間的同步和異步執(zhí)行,通過(guò)示例代碼,展示了如何使用std::condition_variable的wait和notify接口進(jìn)行線程間同步2024-09-09
Qt利用QChart實(shí)現(xiàn)實(shí)時(shí)波形圖的繪制
這篇文章主要介紹了Qt如何利用QChart實(shí)現(xiàn)實(shí)時(shí)波形圖的繪制,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定是參考價(jià)值,需要的可以參考一下2022-06-06
C 語(yǔ)言基礎(chǔ)之初識(shí) C 語(yǔ)言常量
C語(yǔ)言中的常量分為以下幾種:字面常量、const修飾的常變量、#define定義的標(biāo)識(shí)符常量等,下面我們將詳細(xì)對(duì)C語(yǔ)言這幾個(gè)常量做介紹,感興趣的小伙伴可以參考一下2021-09-09
C++訪問(wèn)注冊(cè)表獲取已安裝軟件信息列表示例代碼
這篇文章主要介紹了c++通過(guò)讀取注冊(cè)表獲得本機(jī)已安裝軟件信息的方法,大家參考使用吧2013-11-11

