默認構造函數

1、構造函數

一、什么是構造函數

c++中有一種特殊的成員函數,他的名字和類名相同,沒有返回值,而在創建對象時會自動執行,類中的數據成員的初始化往往通過構造函數來實現。完成類中數據成員的初始化,同時也是類中的成員函數,但是比較特殊

二、如何給構造函數傳參

有參構造,在定義對象是=時給出實參:類名 實例名(實參1,實參2,.....)

構造函數不需用戶調用,也不能被用戶調用,在創建對象時會被自動調用,但是在聲明一個類的指針對象時,構造函數不會被調用,當new一個空間的時候,構造函數也會被調用。

如果用戶自己沒有定義構造函數,則C++系統會自動生成一個構造函數,只是這個構造函數的函數體是空的,也沒有參數,不執行初始化操作。

在構造函數的函數體中不僅可以對數據成員賦初值,而且可以包含其他語句。但是一般不提倡在構造函數中加入與初始化無關的內容,以保持程序的清晰。

對于無參構造函數,在創建對象時,不可以寫成:類名 對象名()

//構造函數的主要功能是完成類中數據成員的初始化,同時它也是類中的一個成員函數,但是比較特殊
class stu
{public:string name;int age;/* stu(string n,int a,int myid){cout << "構造函數" << endl;name = n;age = a;id = myid;}*/stu(){name = "temp";age = 0;id = 100;}void print()//根據有無形參,構造函數分為:有參構造函數 和無參構造函數{cout << name << age<<":"<<id  << endl;}private:int id;};int main()
{//傳統的初始化成員的方式主要針對類中的公有數據成員是有效的,如果存在私有成員或受保護成員 則在類外初始化無法實現/* stu s1;s1.name = "sdfd";s1.age = 12;stu s2 = { "yyy",33 };s2.print();*/// -----------------------------------//構造函數不需要用戶去顯式調用,在創建類對象時,會自動調用該類的構造函數// stu s1("zhangsan",33,1001);//   stu s2;//創建對象時 如果該類的構造函數沒有形參,則可以省略對象后的小括號。// s2.print();//temp0:100return 0;
}
class stu
{public:string name;int age;stu(string n,int a,int myid) //一個類中可以存在多個構造函數{cout << "構造函數" << endl;name = n;age = a;id = myid;// print();}stu()//在C++中,無參構造函數也稱為默認構造函數,如果構造函數提供的形參全是默認形參類型,則該構造也屬于默認構造函數{name = "temp";age = 0;id = 100;}void print()//根據有無形參,構造函數分為:有參構造函數 和無參構造函數{cout << name << age<<":"<<id  << endl;}private:int id;};int main()
{stu s1("zhangsan",33,1001);//構造函數的調用時機時在創建對象時,創建幾個對象 就調用幾次構造函數stu s2;//創建對象時 如果該類的構造函數沒有形參,則可以省略對象后的小括號。s2.print();//temp0:100return 0;
}

int add(int num1,int num2)
{return num1 + num2;
}int sub(int num1, int num2)
{return num1 - num2;
}int mul(int num1, int num2)
{return num1 * num2;
}int   div1(int num1, int num2)
{return num1 / num2;
}int main()
{int num1, num2;cin >> num1 >> num2;cout<<   add(num1, num2)<<endl;cout << sub(num1, num2) << endl;cout << mul(num1, num2) << endl;cout << div1(num1, num2)<< endl;return 0;
}class cal
{
public:int num1;int num2;cal(int a, int b){num1 = a;num2 = b;}int add(){return num1 + num2;}int sub(){return num1 - num2;}int mul(){return num1 * num2;}int   div1(){return num1 / num2;}};int main()
{int num1, num2;cin >> num1 >> num2;//cout<<   add(num1, num2)<<endl;//cout << sub(num1, num2) << endl;//cout << mul(num1, num2) << endl;//cout << div1(num1, num2)<< endl;cal jsq(num1, num2);cout << jsq.add() << endl;cout << jsq.sub() << endl;cout << jsq.mul() << endl;cout << jsq.div1() << endl;return 0;
}

三、參數初始化列表

成員初始化表的一般形式為:

構造函數名(【參數表】):數據成員名1(初始值1),數據成員2(初始值2),,,,,,,,,,

{

? ? ? ? ?//構造函數體

}

1、執行帶參數初始化列表的構造函數時,先執行初始化列表,后執行構造的函數體代碼

2、初始化列表可以用于全部成員變量,也可以只用于部分成員變量

3、初始化的順序和其在類中聲明時的順序是一致的,與列表的先后順序無關

4、成員初始化列表只能用于構造函數

class stu
{
public:string name;int age;const int a;//常數據成員int& temp;//引用類型的數據成員   name("laoguo")  name="laoguo"//初始化列表中的成員的初始化順序和書寫順序無關,和成員在類中的定義順序有關stu(int kk):a(10),name("laoguo"),temp(kk) //當構造函數中的形參比較多時,用初始化列表可以提高程序的性能{age = 12;/*  name = "";age = 12;a = 1000;*/}void print(){cout << name << age << ":" << id << endl;}private:int id;};int main()
{stu s1(30);s1.print();return 0;
}
class date
{
public:int year;int month;int day;date(int y, int m, int d) //一旦類中用戶提供了構造函數,系統不會在為該類自動生成{year = y;month = m;day = d;}/*date(){year = 0;month = 0;day = 0;}*/};class stu
{
public:string name;int age;date bir;//3.當用另一個類對象作為當前類的數據成員時,如果該類沒有提供默認構造函數,此時需要通過初始化列表的方式來初始化該對象。stu(string n, int a, int y, int m, int d):bir(y,m,d){name = n;age = a;}};int main()
{return 0;
}

四、默認構造函數

2、拷貝構造函數

對類中的數據成員進行初始化

需要用到多個完全相同的對象,要將對象在某一個瞬間的狀態保留下來,這就是對象的賦值機制,用一個已有的對象快速地復制處多個相同的對象,如Box1,Box2(Box1)去克隆處一個新對象Box2。

拷貝構造函數的本質是定義對象之間的規則,確定了那些成員需要拷貝,那些不需要拷貝

拷貝構造函數的一般格式:A(const A & a)

class stu
{
public:string name;int age;stu(string n,int a,int myid){name = n;age = a;id = myid;}stu() {}void print(){cout << name << age <<"#" << id << endl;}private:int id;};int main()
{stu s1("laogup", 23,1001);stu s2;//通過賦值運算符,可以將=右邊對象的所有數據成員拷貝到=左邊的對象中,用賦值實現拷貝是全拷貝。s2 = s1;//同類型的對象之間可以相互賦值,主要將一個對象中的數據成員值賦值給另外一個對象//如果在實現對象間拷貝的時候 你想有所選擇的拷貝,需要通過拷貝構造函數s2.print();return 0;
}
class stu
{
public:string name;int age;string s_name;stu(string n,int a,string sname){cout << "普通構造函數" << endl;name = n;age = a;s_name = sname;}//拷貝構造函數 特點:只有一個形參并且該形參屬于當前所在類的類類型,拷貝構造的形參不能采用值傳遞stu(const stu& temp){cout << "拷貝構造函數" << endl;//定義temp與當前對象之間的拷貝原則name = "";age = 0;s_name = temp.s_name;}stu() {}void print(){cout << name << age<<"#" << s_name << endl;}};int main()
{stu s1("laoguo", 23,"建大華清");// stu s2(s1);//實現了用s1對象來初始化s2對象  ,如果用戶沒有定義拷貝構造,系統會自動生成一個,并實現全拷貝stu s2 = s1;// stu s2(s1) 都匹配的是拷貝構造函數/* stu s2;s2 = s1;*/s2.print();//0#建大華清return 0;
}
class stu
{
public:string name;int age;string s_name;stu(string n,int a,string sname){cout << "普通構造函數" << endl;name = n;age = a;s_name = sname;}//拷貝構造函數 特點:只有一個形參并且該形參屬于當前所在類的類類型,拷貝構造的形參不能采用值傳遞stu(const stu& temp){cout << "拷貝構造函數" << endl;//定義temp與當前對象之間的拷貝原則name = "";age = 0;s_name = temp.s_name;}stu() {}void print(){cout << name << age<<"#" << s_name << endl;}};void test(stu tt)
{}stu mytest()
{stu s2("ttt", 44, "sdf");return s2;//3 在函數中返回一個對象}int main()
{stu s1("laoguo", 23,"建大華清");test(s1);//2用一個對象做值傳遞// 1. stu s2(s1);mytest();return 0;
}

3、析構函數

析構函數是一個特殊的由用戶定義的成員函數,當該類的對象離開了他的域(對象的生命周期結束時)或者delete表達式應用到一個該類的對象的指針上時,析構函數會自動被調用

析構函數的名字是在類名前加上波浪線~,他不返回任何值,也沒有任何參數,我們可以為一個類定義多個構造函數,但是我們只能提供一個析構函數,他將應用于類的所有對象上。

主要功能是做清理和收尾

class stu
{
public:string name;int age;string s_name;stu(string n,int a,string sname){cout << "普通構造函數" << endl;name = n;age = a;s_name = sname;}stu() { cout << "默認構造函數" << endl; }void print(){cout << name << age<<"#" << s_name << endl;}//析構函數: ~類名(){}    不需要用戶主動調用,當某個對象在離開它的域就會觸發 該對象所屬類中的析構函數~stu() //析構函數的作用:清理收尾工作{cout << "析構函數" << endl;}};void test()
{static stu s3;}int main()
{stu s1;test();cout << "#############" << endl;stu s2;return 0;
}

4、匿名對象

只存在于構造該對象的那行代碼,離開構造對象的哪行代碼后立即調用該對象

int main()
{//匿名對象的創建:類型(【實參列表】),他的生存周期只存在于改行代碼stu();//類名 對象名(【實參列表】)cout<<"#######"<<endl;return 0;
}

?5、this關鍵字

class stu
{
public:string name;int age;string s_name;// const int *a        int * const astu(string name,int age,string s_name)//在C++中,一般來說 成員函數中都有一個隱形的形參叫this     this == stu * const this{cout << "inner:"<<this << endl;//this指向的是當前對象的指針,this只能在類的成員函數內使用,類外不可以使用this->name = name;//1.當成員函數中 局部變量與類中的數據成員出現重名 ,此時可以通過this關鍵字來加以區分 this->age = age;this->s_name = s_name;}void print(){cout << name <<this-> age<<"#" << s_name << endl;}stu mytest(){return *this;//2.  返回當前對象}};int main()
{stu s1("laoguo", 12, "建大");cout << "outer" << &s1<< endl;stu s2("laoguo1", 12, "建大");
//inner:00A0FAFC
//outer00A0FAFCreturn 0;
}

6、對象的動態建立和釋放

如果我們希望在需要用到對象時才建立對象,在不需要用該對象時就撤銷它,釋放它所占的內存空間以供別的數據使用,除了沿用C語言提供的malloc與free函數外,還可以:

在c++利用new操作符在堆區開辟數據空間,手動開辟就需要手動釋放,釋放時利用delete操作符。

一、new運算符

作用:分配內存(堆上),調用構造函數

一般格式:new 類型(初值單值)

? ? ? ? ? ? ? ? ? new 類型 {初值多值}

? ? ? ? ? ? ? ? ? ?new類型【大小】;

二、delete運算符

例子:


class stu
{
public:string name;int age;string s_name;stu(string name,int age,string s_name){cout << "inner:"<<this << endl;this->name = name;this->age = age;this->s_name = s_name;}void print(){cout << name <<this-> age<<"#" << s_name << endl;}~stu(){cout << "析構函數" << endl;}};int main()
{//在堆上創建單對象和釋放單個對象的案例int *pt= new int;//在堆上構建一個int大小的內存并返回給內存的首地址*pt = 1000;//對堆對象進行寫操作cout << *pt << endl;//進行讀操作int* pt1 = new int(10);//在堆上創建一個int對象 同時將其初始化為10cout << *pt1 << endl;stu* pp = new stu("laoguo",22,"北大");//在堆上構建一個類類型對象stucout << pp->name << endl;pp->print();//new和delete要成對出現delete pp;//當對一個堆對象施加delete 也會觸發該類的析構函數return 0;
}
class stu
{
public:string name;int age;string s_name;stu(string name,int age){cout << "inner:"<<this << endl;this->name = name;this->age = age;}void print(){cout << name <<this-> age<< endl;}~stu(){cout << "析構函數" << endl;}};//批量在堆上構建對象的案例
int main()
{//  int* pt = new int[10]; //在堆上構建一個可以容納10個整數類型的數組;//int* pt = new int[10]{ 11, 22, 33, 1, 2, 3, 4, 5, 6, 7 };//構建動態數組的同時并完成其整體的初始化//for (int i = 0; i < 10; i++)//{//    cout << pt[i] << endl;//}stu* pp = new stu[3]{ {"kk",3},{"pp",5},{"yy",7}};for (int i = 0; i < 3; i++){cout << pp[i].name << pp[i].age << endl;}delete[] pp;return 0;
}

7、共用數據的保護(const)

一、常對象

格式:const <類名> <對象名>;

<類名> const <對象名>;

//常對象的 案例class stu
{
public:string name;int age;stu(string name,int age){cout << "inner:"<<this << endl;this->name = name;this->age = age;}void test(string ljs){name = ljs;}void print(){cout << name <<this-> age<< endl;}~stu(){cout << "析構函數" << endl;}};int main()
{//通過常對象,可以訪問類中的數據成員,但是不可以對其做修改。一旦定義了常對象 相當于對類中的所有數據成員都加了const 約束const stu s1("laoguo", 22);//定義一個stu類型的常對象cout << s1.name << endl;//s1.test(); 常對象不可以調用類中的非 常成員函數//  s1.name = "laozhang"; 是錯的return 0;
}

二、常數據成員

//常數據成員的使用案例
class stu
{
public:string name;int age;const int score;//常數據成員,不要試圖對常數據成員中的值進行修改,但是可以讀stu(string name,int age,int sc):score(sc)//對與常數據成員需要通過初始化列表來對其初始化{cout << "inner:"<<this << endl;this->name = name;this->age = age;}void print(){cout << name <<this-> age<<score<< endl;}~stu(){cout << "析構函數" << endl;}};int main()
{stu s1("laozhang", 12, 80);return 0;
}

三、常成員函數

//常成員函數 使用案例class stu
{
public:string name;int age;const int score;//常數據成員,不要試圖對常數據成員中的值進行修改,但是可以讀stu(string name,int age,int sc):score(sc)//對與常數據成員需要通過初始化列表來對其初始化{cout << "inner:"<<this << endl;this->name = name;this->age = age;}//常成員函數void mytest()const{cout << age << endl;cout << "加const的函數";//  age = 33;//在常 成員函數眼中,類中的任何數據成員都是神圣不可侵犯(只能讀不可以改)//print();是錯的,在常成員函數中 不可以調用類中非 常成員函數}//void mytest()//在類中 重載時 有一個特殊的情況,就是函數后加const 和不加const 可以重載成功//{//    cout << "不加const的函數";////}void print(){cout << name <<this-> age<<score<< endl;//age = 33;mytest();//類中的非 常成員函數可以調用類中的常成員函數}~stu(){cout << "析構函數" << endl;}};int main()
{stu s1("laozhang", 12, 80);s1.mytest();const stu s2("sdf", 33, 55);//常對象可以調用類中常成員函數s2.mytest();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86493.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86493.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86493.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

帶標簽的 Docker 鏡像打包為 tar 文件

現在還有人用docker嗎 要將帶標簽的 Docker 鏡像打包為 tar 文件&#xff0c;請使用 docker save 命令。以下是詳細操作指南&#xff1a; 一、單鏡像打包&#xff08;推薦方式&#xff09; # 基礎格式 docker save -o [輸出文件名].tar [鏡像名]:[標簽]# 示例&#xff1a;將…

基于GPS-RTK的履帶吊車跑偏檢測技術方案

基于GPS-RTK的履帶吊車跑偏檢測技術方案 1. 引言 1.1 項目背景 履帶吊車作為重型工程機械&#xff0c;其行駛穩定性直接關系到作業安全和設備壽命。跑偏現象會導致履帶異常磨損、轉向系統過載&#xff0c;嚴重時可能引發側翻事故。傳統檢測方法&#xff08;如激光測距或人工觀…

勾正數據大數據開發面試題整理-20250625

最近面了家公司&#xff0c;想看看自己多年不準備面試&#xff0c;靠著老本能面試成啥樣&#xff0c;算是試試水吧&#xff0c;一面過了&#xff0c;二面有個算法題沒答出來&#xff0c;整體答得狀態也不太好&#xff0c;應該是沒過。 一面 先來說說一面吧&#xff0c;一面是…

基于中國香港會計準則差異,中國企業在香港推廣ERP(SAP、Oracle)系統需要注意的細節

核心在于&#xff1a;ERP通常按單一會計準則設計主數據架構&#xff0c;但跨國企業需要同時滿足兩地報表要求。 用戶常見的場景包括&#xff1a; 1 科目體系能否同時承載CAS的專項儲備和HKFRS的禁止計提&#xff1f; 2 資產模塊如何兼容不同的減值轉回規則&#xff1f; 3 關聯…

【編譯原理】期末復習知識總結

目錄 題型 總結 編譯五大組成部分 編譯與解釋方式區別&#xff1f; 前端&#xff0c;后端&#xff0c;Why&#xff1f; 概念 推導、歸約 短語、簡單短語、句柄 文法 分類 正則文法&#xff08;3型&#xff09; NFA、DFA、最小化 自上而下語法分析&#xff08;推導…

【軟考高級系統架構論文】論微服務架構及其應用

論文真題 論微服務架構及其應用近年來,隨著互聯網行業的迅猛發展,公司或組織業務的不斷擴張,需求的快速變化以及用戶量的不斷增加,傳統的單塊(Monolithic) 軟件架構面臨著越來越多的挑戰,已逐漸無法適應互聯網時代對軟件的要求。在這一背景下,微服務架構模式(Microservi…

【人工智能】RAG分塊

在RAG&#xff08;檢索增強生成&#xff09;系統中&#xff0c;文檔分塊&#xff08;Chunking&#xff09;是決定系統性能的核心環節&#xff0c;直接影響檢索精度和生成質量。分塊需平衡語義完整性、檢索效率和上下文保留三大目標。 一、分塊的核心標準 1.1 分塊基礎知識? …

能耗管理新革命:物聯網實現能源高效利用

在全球能源危機與 “雙碳” 目標的雙重壓力下&#xff0c;企業與社會對能耗管理的重視程度達到前所未有的高度。然而&#xff0c;傳統能耗管理方式存在數據采集滯后、分析維度單一、節能措施粗放等問題&#xff0c;無法滿足精細化管理需求。物聯網技術憑借其強大的數據感知、傳…

基于CMS的黃道吉日萬年歷源碼(自適應)

本模板采用帝國cms7.5版UTF-8制作&#xff1b; 適用站點&#xff1a;時間查詢、時差計算、萬年歷、黃道吉日查詢、假期查詢、節氣表等&#xff1b; 源碼優勢&#xff1a;代碼精簡&#xff0c;利于SEO、UI大氣精簡&#xff0c;搜索引擎收錄高&#xff1b; 全站偽靜態無需刷新生成…

如何構建個人AIagent

構建個人AI Agent是一個結合技術實現和場景設計的系統工程&#xff0c;以下是分步驟的詳細指南&#xff0c;涵蓋從需求定義到部署落地的全流程&#xff1a; ?一、明確Agent定位&#xff08;關鍵第一步&#xff09;?? ?角色定義矩陣? 類型典型場景技術復雜度示例信息處理Ag…

lutris登錄不進去

日志 Cannot create Vulkan instance.This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU thatdoes not support Vulkan.ERROR at /home/abuild/rpmbuild/BUILD/vulkan-tools-1.4.313-build/Vulkan-Tools-vulkan-sdk-1.…

緩存與加速技術實踐-NoSQL之Redis配置與優化

目錄 #1.1關系數據庫與非關系型數據庫 1.1.1關心型數據庫 1.1.2非關系型數據庫 1.1.3非關系型數據庫產生背景 #2.1redis簡介 2.1.1redis安裝部署 2.1.2配置參數 #3.1redis命令工具 3.1.1redis-cli命令行工具 3.1.2redis-benchmark測試工具 #4.1redis數據庫常用命令 4.1.1ke…

走近科學IT版:FreeBSD系統下ThinkPad鍵盤突然按不出b、n、/和空格鍵了!

走近科學IT版&#xff1a;FreeBSD系統下ThinkPad鍵盤突然按不出b和n鍵了&#xff01; 很慌&#xff0c;以為鍵盤壞了&#xff0c;在控制臺無法按出b和n&#xff0c;但是在瀏覽器里&#xff0c;可以按出來。 重啟機器&#xff0c;結果在瀏覽器里也按不出來了.... 按Ctrl空格&a…

聚銘網絡入選嘶吼《中國網絡安全細分領域產品名錄》“云平臺安全管理”與“態勢感知”雙領域TOP10

近日&#xff0c;在嘶吼安全產業研究院發布的《中國網絡安全細分領域產品名錄》中&#xff0c;聚銘網絡憑借其核心產品——聚銘云端安全管家與聚銘安全態勢感知與管控系統&#xff0c;分別入選“云平臺安全管理”與“態勢感知”兩大關鍵細分領域TOP10榜單&#xff0c;充分展現了…

DEYOLO 全面復現,將雙增強跨模態目標檢測網絡 DEYOLO 融合到 YOLOFuse 框架

模型架構模態精度 P召回率 RmAP50mAP50-95模型大小(MB)計算量(GFLOPs)yolov8n (baseline)RGB0.8880.8290.8910.5006.28.1yolo-fuse-中期特征融合RGBIR0.9510.8810.9470.6012.613.2yolo-fuse-早期特征融合RGBIR0.9500.8960.9550.6235.26.7yolo-fuse-決策級融合RGBIR0.9560.9050.…

python基于Django+mysql實現的圖書管理系統【完整源碼+數據庫】

摘要 隨著信息技術與教育現代化的深度融合&#xff0c;圖書管理系統的智能化與自動化成為提升資源利用效率的關鍵需求。本文基于Python語言&#xff0c;采用Django框架與MySQL數據庫設計并實現了一套功能完備的圖書管理系統&#xff0c;旨在通過信息化手段優化圖書借閱流程、強…

論軟件設計方法及其應用

20250427-作 題目 軟件設計&#xff08;Software Design&#xff0c;SD)根據軟件需求規格說明書設計軟件系統的整體結構、劃分功能模塊、確定每個模塊的實現算法以及程序流程等&#xff0c;形成軟件的具體設計方案。軟件設計把許多事物和問題按不同的層次和角度進行抽象&…

QT 自定義ComboBox,實現下拉框文本顏色設置

最近在做項目中遇到需求&#xff0c;在下拉框中&#xff0c;文本需要設置不同的顏色&#xff0c;遂網上了解了一番后&#xff0c;得出以下代碼&#xff0c;可以完美實現效果&#xff0c;現分享出來&#xff01; 1.實現效果 2.自定義類 colorcombobox.h #ifndef COLORCOMBOBOX…

【時間戳】

在編程競賽和高效數據處理場景中&#xff0c;時間戳技巧是一種極其高效的標記方法&#xff0c;常用于避免頻繁清空數組或 map&#xff0c;提高算法運行效率。本文將從定義、應用場景、模板代碼、技巧細節等方面系統整理時間戳的使用方式。 一、時間戳技巧是什么&#xff1f; 時…

json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig)

有一次爬蟲遇到了json的字符串響應對象 然后轉為json對象 報這個錯誤 raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0) 意思是叫…