目錄:?
1. C的提高 1-131P 時間七天?
2. C++的基礎 132-286P 時間八天?
3. C++的提高 287-378P 時間五天?
4. C/C++的數據結構 379-482P 時間五天?
5. C/C++的設計模式基礎 483-540P 時間三天
?
視頻資料:https://www.bilibili.com/video/av27904891?from=search&seid=10891514449061956870
P171 構造和析構的基礎知識
構造函數
1、構造函數定義及調用
1)C++中的類可以定義與類名相同的特殊成員函數,這種與類名相同的成員函數叫做構造函數;
2)構造函數在定義時可以有參數;
3)沒有任何返回類型的聲明。
2、構造函數的調用
自動調用:一般情況下C++編譯器會自動調用構造函數
手動調用:在一些情況下則需要手工調用構造函數
?
析構函數
1、析構函數定義及調用
1)C++中的類可以定義一個特殊的成員函數清理對象,這個特殊的成員函數叫做析構函數
語法:~ClassName()
2)析構函數沒有參數也沒有任何返回類型的聲明
3)析構函數在對象銷毀時自動被調用
4)析構函數調用機制
2、C++編譯器自動調用
?
#include<iostream> using namespace std;class Test { public:Test()//無參數 構造函數 {cout<<"我是構造函數"<<endl;}~Test()//析構函數 {cout<<"我是析構函數"<<endl;} private: };//給對象搭建一個舞臺,研究對象的行為 void objplay() {//先創建的對象后釋放 Test t1;Test t2; }void main() {objplay();system("pause"); }
?
?P172? 構造和析構的用途演示
#include<iostream> using namespace std;class Test { public:Test()//無參數 構造函數 {a=10;//作用:完成對屬性的初始化工作p=(char *)malloc(100);strcpy(p,"aaa");cout<<"我是構造函數"<<endl;}void printfP(){cout<<p<<endl;cout<<a<<endl;}~Test()//析構函數 {if (p!=NULL){free(p);}cout<<"我是析構函數"<<endl;} private:int a;char *p; };//給對象搭建一個舞臺,研究對象的行為 void objplay() {//先創建的對象后釋放 Test t1;t1.printfP();printf("分隔符\n");Test t2;t2.printfP(); }void main() {objplay();system("pause"); }
?
?輸出結果
?
?P173? 構造函數的調用(無參數和有參調用)
#include<iostream> using namespace std;class Test2 { public:Test2() //無參數構造函數 {m_a=0;m_b=0;cout<<"無參數構造函數"<<endl;}Test2(int a)//有參數構造函數 {m_a=a;m_b=0;cout<<"a:"<<m_a<<endl;printf("這是等號構造函數\n");}Test2(int a,int b)//有參數構造函數 {m_a=a;m_b=b;cout<<"有參數構造函數"<<endl;}//賦值構造函數(copy構造函數)Test2(const Test2 &obj){cout<<"我也是構造函數"<<endl;} public:void printT(){cout<<"普通成員函數"<<endl;} private:int m_a;int m_b; };//調用有參數構造函數3種方法 void main() {//Test2 t1;//調用無參數構造函數//1. 括號法Test2 t1(1,2);//C++編譯器自動的調用構造函數 t1.printT();//2. c++對=操作符進行了功能增強 Test2 t2=(3,4,5);Test2 t3=5;//3. 直接調用構造函數 手動的調用構造函數Test2 t4=Test2(1,2);//匿名對象(匿名對象的去和留) system("pause"); }
?
?輸出結果:
?
P175? 為什么需要構造和析構函數
1、構造函數的調用方法:自動調用(按照規則調用)
2、顯示的初始化類的屬性或其他資源
#include<iostream> using namespace std;class Test3 { public:void init(int _a,int _b){a=_a;b=_b;} protected: private:int a;int b; };void main() {//類沒有提供構造函數 C++編譯器會自動給你提供一個默認的構造函數//類沒有提供copy構造函數 C++編譯器會自動給你提供一個默認的copy構造函數 Test3 t1;t1.init(2,3);Test3 tArray[3];tArray[0].init(1,2);tArray[1].init(1,2);tArray[2].init(1,2);//在這種場景之下 顯示的初識化方案顯得很蹩腳Test3 t21;t21.init(1,2);Test3 t22;t22.init(1,2);Test3 t23;t23.init(1,2);Test3 tArray2[3]={t21,t22,t23};//在這種場景下 滿足不了編程需要//Test3 tArray2[1999]={t21,t22,t23}; system("pause"); }
?
?P176? copy構造函數調用時機1和2
#include<iostream> using namespace std;class Test4 { public:Test4() //無參數構造函數 {m_a=0;m_b=0;cout<<"無參數構造函數"<<endl;}Test4(int a)//有參數構造函數 {m_a=a;m_b=0;cout<<"a:"<<m_a<<endl;printf("這是等號構造函數\n");}Test4(int a,int b)//有參數構造函數 {m_a=a;m_b=b;cout<<"有參數構造函數"<<endl;}//賦值構造函數(copy構造函數)Test4(const Test4 &obj){cout<<"我也是構造函數"<<endl;m_b=obj.m_b+100;m_a=obj.m_a+100;} public:void printT(){cout<<"普通成員函數"<<endl;cout<<"m_a:"<<m_a<<endl;} private:int m_a;int m_b; };//1. 賦值構造函數 用1個對象去初始化另外一個對象 void main_number1() {Test4 t1(1,2);Test4 t0(1,2);t0=t1;//用t1給t0 賦值操作和初始化是兩個不同的概念//第一種 調用方法Test4 t2=t1;//用t1初始化t2 t2.printT();system("pause"); } //2. 第二種調用時機 void main() {Test4 t1(1,2);Test4 t0(1,2);Test4 t2(t1);//用t1對象初始化t2對象 t2.printT(); }
?
?P178? ?copy構造函數調用時機3
#include<iostream> using namespace std;class Location { public:Location( int xx = 0 , int yy = 0 ) { X = xx ; Y = yy ; cout << "Constructor Object.\n"<<endl ; }Location( const Location & p ) //拷貝構造函數 完成對象的初始化 { X = p.X ; Y = p.Y ; cout << "Copy_constructor called." << endl ; }~Location() { cout << X << "," << Y << " Object destroyed." << endl ; }int GetX () { return X ; } int GetY () { return Y ; } private : int X , Y ; } ;//業務函數 形參是一個元素 void f ( Location p ) { cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ; }void mainobjplay() { Location a(1,2);Location b=a; //形參是一個元素,函數調用,會執行實參變量初始化形參變量 f(b);//b實參去初始化形參p,會調用copy構造函數 } void main() { mainobjplay();system("pause"); }
?輸出結果:
?