? ? ? ? 今天要學三個知識點:引用、內(nèi)存分配及重載
一、引用 &
引用是C++對C的一個非常重要的擴充,引用的引入,重要的作用是用于參數(shù)和返回值,無需再考慮值傳遞地址傳遞的問題了
1.1 引用的概念
所謂引用,其實相當于給變量起個別名,但是,不會給引用分配內(nèi)存空間:例如, 宋江的別名? 及時雨
1.2 引用的定義
1> 定義格式:數(shù)據(jù)類型? &引用名 = 引用的目標;
例如:int num = 520;? ? ? ? int &ref= num;
2> 引用的注意事項
1、定義引用時,必須給引用進行初始化,否則會報錯
2、系統(tǒng)不會給引用重新分配內(nèi)存空間,引用與引用的目標是同一內(nèi)存空間
3、引用的目標一旦確定,后期不能進行修改
4、一個目標可以有多個引用,多個引用都是一個內(nèi)存空間
5、定義引用時,需要使用&來說明身份,但是使用引用時,跟使用目標用法一樣
3> 總結(jié)&的用途
1、&后面跟變量名,表明取得該變量的地址
2、作為雙目運算符,一個&表示按位與運算
3、作為雙目運算符,兩個&&表示邏輯與運算
4、定義引用時, 表明身份的象征,一個&表明是左值引用,兩個&&表明是右值引用
5、對于一個&使用時,如果左側(cè)有數(shù)據(jù)類型,表明正在定義引用,如果左側(cè)沒有數(shù)據(jù)類型,表明是取地址運算符
1.3 引用的基本使用
#include <iostream>
using namespace std;
int main()
{
? ? int num = 520;? ? ? ? ? //定義一個變量
? ? //定義一個引用,其目標為num
? ? int &ref = num;? ? ? ? ? //定義引用時必須初始化,否則報錯
? ? cout<<"num = "<<num<<"? ? ? ref = "<<ref<<endl;? ? ? //值相同
? ? cout<<"&num = "<<&num<<"? ? ? &ref = "<<&ref<<endl;? //地址相同
? ? cout<<"size of num = "<<sizeof(num)<<"? ? ? size of ref = "<<sizeof(ref)<<endl;? // 所占內(nèi)存大小一致
? ? cout<<"type of num = "<<typeid(num).name()<<"? ? ? type of ref = "<<typeid (ref).name()<<endl;? //數(shù)據(jù)類型一致
? ? ref = 1314;
? ? cout<<"num = "<<num<<"? ? ? ref = "<<ref<<endl;? //連個名字一塊變
? ? //再定義一個新的變量
? ? int key = 999;
? ? ref = key;? ? ? ? ? ? ? //這是給ref的空間重新賦值,而不是給引用重新設置目標
? ? cout<<"&num = "<<&num<<"? ? ? &ref = "<<&ref<<"? &key = "<< &key <<endl;
? ? //再定義一個引用,目標為num
? ? int &ref1 = num;
? ? cout<<"&num = "<<&num<<"? ? ? &ref = "<<&ref<<"? &ref1 = "<< &ref1<<endl;
? ? //再定義一個引用,目標為ref
? ? int &ref2 = ref;? ? ? ? ? ? //沒有多級引用,引用的引用也是一級引用,相當于給目標設置引用
? ? cout<<"&num = "<<&num<<"? ? ? &ref = "<<&ref<<"? &ref1 = "<< &ref1<<"? &ref2 = "<< &ref2<<endl;
? ? return 0;
}
1.4 引用作為函數(shù)參數(shù)
1> 引用作為函數(shù)參數(shù),傳遞的是實參本身,本質(zhì)上是地址傳遞
2> 相比于普通變量和指針做形參,傳遞效率更高
#include <iostream>
using namespace std;
//定義值傳遞函數(shù)
void swap1(int a, int b)
{
? ? //交換三部曲
? ? int temp = a;
? ? a = b;
? ? b = temp;
? ? cout<<"swap1:: a = "<<a<<" b = "<<b<<endl;? ? ? ?
}
//定義swap2函數(shù)
void swap2(int *p, int *q)
{
? ? int *temp = p;
? ? p = q;
? ? q = temp;
? ? cout<<"swap1:: *p = "<<*p<<" *q = "<<*q<<endl;? ? ?
}
//定義swap3函數(shù)
void swap3(int *p, int *q)
{
? ? int temp = *p;
? ? *p = *q;
? ? *q = temp;
? ? cout<<"swap1:: *p = "<<*p<<" *q = "<<*q<<endl;? ? ?
}
//定義引用傳遞函數(shù)
void swap4(int &a, int &b)
{
? ? //交換三部曲
? ? int temp = a;
? ? a = b;
? ? b = temp;
? ? cout<<"swap4:: a = "<<a<<" b = "<<b<<endl;? ? ? ? ? ? //520? 1314
}
int main()
{
? ? int num = 520;
? ? int key = 1314;
? ? //1、值傳遞
? ? swap1(num, key);
? ? cout<<"調(diào)用swap1后:num ="<<num<<"? key = "<<key<<endl;? //520? 1314
? ? //2、傳遞地址的值傳遞
? ? swap2(&num, &key);
? ? cout<<"調(diào)用swap2后:num ="<<num<<"? key = "<<key<<endl;? //520? 1415
? ? //3、 地址傳遞
? ? swap3(&num, &key);
? ? cout<<"調(diào)用swap3后:num ="<<num<<"? key = "<<key<<endl;? //1314? 520
? ? //4、引用傳遞
? ? swap4(num, key);
? ? cout<<"調(diào)用swap4后:num ="<<num<<"? key = "<<key<<endl;? ? ? ? //520? 1314
? ? return 0;
}
1.5 引用作為函數(shù)的返回值
1> 引用作為函數(shù)的返回值是一個左值
2> 引用作為函數(shù)的返回值返回生命周期比較長的變量
1、靜態(tài)局部變量
2、全局變量
3、堆區(qū)申請的空間內(nèi)容
4、主調(diào)函數(shù)中通過地址傳遞進來的參數(shù)的內(nèi)容
#include <iostream>
using namespace std;
//定義一個普通函數(shù),普通函數(shù)的返回值是一個右值,只可讀,不可寫
int fun1()
{
? ? int num = 520;
? ? return num;
}
//定義指針函數(shù)
int *fun2()
{
? ? static int num = 666;
? ? return #
}
//定義引用函數(shù)
int &fun3()
{
? ? static int num = 1314;
? ? return num;? ? ? ? //返回堆區(qū)空間的引用
}
int main()
{
? ? cout<<"fun1() = "<<fun1()<<endl;? ? ? ? //520
? ? //fun1() = 1314;? ? ? ? ? ? ? //普通函數(shù)的返回值是一個右值
? ? cout<<"*fun2() = "<<*fun2()<<endl;? ? ? ? //666
? ? *fun2() = 999;? ? ? ? ? ? ? ? ? //指針函數(shù)的返回值是一個左值
? ? cout<<"*fun2() = "<<*fun2()<<endl;? ? ? ? //999
? ? //定義引用接受函數(shù)返回的結(jié)果
? ? int &ref = fun3();
? ? cout<<"fun3() = "<<ref<<endl;? ? ? ? //1314
? ? fun3() = 555;? ? ? ? ? ? ? //引用函數(shù)的返回值是一個左值
? ? cout<<"ref = "<<ref<<endl;
? ? return 0;
}
1.6 常引用
1> 常引用引用的目標可以是非常變量,本質(zhì)上包含目標不被修改
2> 不可以通過常引用更改目標的值,但是可以通過目標自身進行更改
3> 常引用常用來修飾參數(shù)和返回值,表示包含參數(shù)或函數(shù)返回值不被修改
4> 常引用可以引用右值
#include <iostream>
using namespace std;
//定義加法函數(shù),形參加上const保護形參數(shù)據(jù)不在函數(shù)體內(nèi)被修改
int Add(const int &m,const int &n)
{
//? ? m = 0;
//? ? n = 0;
? ? return? m+n;
}
int main()
{
? ? int num = 520;
? ? //定義一個常引用,目標為非常變量
? ? const int &ref = num;
? ? cout<<"ref = "<<ref<<endl;? ? ? ? //可以對數(shù)據(jù)進行讀操作
? ? //ref = 1314;? ? ? ? ? ? ? //不能通過常引用對目標進行更改
? ? num = 1314;
? ? cout<<"ref = "<<ref<<endl;? ? //1314
//? ? int a = 3;
//? ? int b = 5;
? ? cout<<Add(3,5)<<endl;
? ? //常引用引用右值的案例1
? ? const int &r = 1314 + 100;
? ? //常引用引用右值的案例2
? ? const double &r1 = (double)num;? ? ? //const修飾的引用,可以引用臨時值
? ? const int &r2 = Add(3,4);? ? ? ? ? ? //const修飾的引用,可以引用普通函數(shù)的返回值
? ? //double d = (double)num;
? ? return 0;
}
1.7 右值引用(了解)
1> 定義格式:數(shù)據(jù)類型 &&引用名 = 引用目標;
2> 左值引用的目標必須是一個左值,右值引用的目標必須是一個右值
3> 可以使用move函數(shù)進行將左值轉(zhuǎn)換成右值
#include <iostream>
using namespace std;
int main()
{
? ? int num = 520;
? ? int &r1 = num;? ? ? ? ? //左值引用,能引用左值
? ? //int &r2 = 520;? ? ? ? ? ? ? //左值引用不能引用右值
? ? int &&r3 = 1314;? ? ? ? ? //右值引用可以引用右值
? ? //int &&r4 = num;? ? ? ? ? ? //右值引用不能引用左值
? ? int &r5 = r3;? ? ? ? ? ? //右值引用本身是一個左值
? ? int &&r6 = move(num);? ? ? //move函數(shù)的功能是將一個值轉(zhuǎn)換成右值
? ? return 0;
}
1.8 引用作為結(jié)構(gòu)體的成員
如果結(jié)構(gòu)體中有引用成員,那么對該成必須進行初始化工作
#include <iostream>
using namespace std;
//聲明一個結(jié)構(gòu)體類型
struct Stu
{
? ? string name;
? ? int age;
? ? double &score;? ? ? ? ? //引用成員
};
int main()
{
? ? double s = 90;
? ? struct Stu s1 = {"zhangpp", 18, s};? ? ? ? ? //其他成員都可以不進行初始化,但是引用成員必須初始化
? ? cout<<"score = "<<s1.score<<endl;? ? ? ? ? ? //90
? ? return 0;
}
1.9 指針與引用的區(qū)別
1> 指針記錄的是變量的地址,而引用變量本身
2> 定義引用時必須初始化,而定義指針不是必須初始化
3> 指針需要分配8字節(jié)的內(nèi)存空間,而引用與目標是同一內(nèi)存空間,無需額外分配
4> 指針可以有多級指針,但是引用只有一級引用
5> 指針后期可以更改指向,而引用一旦綁定后期就不能進行更改目標了
6> const修飾指針時,有修飾指向和值,而const修飾引用時,只有修飾值
7> 指針使用時,需要使用取值運算符進行解引用,而引用使用時跟目標的使用方式一致
8> 沒有引用數(shù)組,但是有數(shù)組引用
#include <iostream>
using namespace std;
//函數(shù)形參使用數(shù)組接受,本質(zhì)上是指針接收
void fun(int brr[], int n)
{
? ? cout<<"sizeof brr = "<<sizeof(brr)<<endl;? ? ? //8
? ? cout<<"sizeof brr = "<<sizeof (brr[0])*n<<endl;? //得到傳入的數(shù)組大小 12
? ? cout<<"&brr = "<<&brr<<endl;
}
//函數(shù)形參使用數(shù)組引用接受數(shù)組,接受的就是數(shù)組本身
void gun(int (&ref)[3])
{
? ? cout<<"sizeof ref = "<<sizeof(ref)<<endl;? ? //12
? ? cout<<"&ref = "<<&ref<<endl;? ? ? ? ? //
}
int main()
{
? ? int arr[3] = {1,2,3};
? ? fun(arr,3);
? ? cout<<"&arr = "<<&arr<<endl;
? ? cout<<"sizeof arr = "<<sizeof (arr)<<endl;
? ? gun(arr);? ? ? //調(diào)用函數(shù)時,傳遞數(shù)組即可
? ? return 0;
}
二、C++中的動態(tài)內(nèi)存分配和回收
1> C++也支持使用malloc、free來完成對堆區(qū)空間的申請和釋放工作,該工作適用于對基本數(shù)據(jù)類型、結(jié)構(gòu)體變量空間申請
2> C++是面向?qū)ο蟮木幊蹋瑢τ趯ο蟮目臻g申請有專門的關(guān)鍵字來完成,new和delete完成對象空間的申請和釋放
2.1 單個內(nèi)存的申請和釋放
1> 申請格式:數(shù)據(jù)類型? *指針名 = new 數(shù)據(jù)類型;
例如:int *p1 = new int;? ? ? ? ? ? ? ? ? //在堆區(qū)申請一個int大小空間的內(nèi)存
2> 釋放格式:delete 指針名;
例如:delete p1;
#include <iostream>
using namespace std;
int main()
{
? ? int *p1 = new int;? ? ? ? //在堆區(qū)申請一個int單位的空間
? ? cout<<"*p1 = "<<*p1<<endl;? ? ? //隨機值
? ? *p1 = 520;? ? ? ? ? ? ? ? ? ? //使用堆區(qū)內(nèi)存空間
? ? cout<<"*p1 = "<<*p1<<endl;? ? ? ? ? ? //520
? ? //在堆區(qū)申請空間后,給初始值
? ? int *p2 = new int(1314);? ? ? ? //在堆區(qū)申請一個int單位的內(nèi)存,并給定初始值為1314
? ? cout<<"*p2 = "<<*p2<<endl;? ? ? ? //1314
? ? //是否內(nèi)存空間
? ? delete p1;
? ? p1 = nullptr;? ? ? ? //(void *)0
? ? delete p2;
? ? p2 = nullptr;
? ? return 0;
}
2.2 連續(xù)內(nèi)存空間的申請和釋放
1> 申請格式:數(shù)據(jù)類型 *指針名 = new 數(shù)據(jù)類型[個數(shù)];
例如:int *p1 = new int[5];? ? ? ? ? ? ? ? ? ? //在堆區(qū)申請5個int大小的恐懼
2> 釋放格式:delete [] 指針名;
例如:delete []p1;? ? ? ? ? ?
#include <iostream>
using namespace std;
int main()
{
? ? //在 堆區(qū)申請空間,不進行初始化工作
? ? int *p1 = new int[5];? ? ? ? ? //在堆區(qū)申請5個連續(xù)的int大小的空間
? ? for(int i=0; i<5; i++)
? ? {
? ? ? ? cout<<p1[i]<<" ";
? ? }
? ? cout<<endl;
? ? //使用堆區(qū)空間
? ? for(int i=0; i<5; i++)
? ? {
? ? ? ? p1[i] = 10+i;
? ? }
? ? for(int i=0; i<5; i++)
? ? {
? ? ? ? cout<<p1[i]<<" ";
? ? }
? ? cout<<endl;
? ? //在堆區(qū)申請空間并初始化
? ? int *p2 = new int[5]{1,2,3,4,5};
? ? for(int i=0; i<5; i++)
? ? {
? ? ? ? cout<<p2[i]<<" ";
? ? }
? ? cout<<endl;
? ? //釋放內(nèi)存空間
? ? delete []p1;
? ? p1 = nullptr;
? ? delete [] p2;
? ? p2 = nullptr;
? ? return 0;
}
練習:在堆區(qū)申請一個長度為5的數(shù)組,用于存放5名學生的成績,自己封裝函數(shù)完成,對5名學生成績的錄入、升序排序、輸出
要求:使用new和delete完成
#include <iostream>
#include <istream>
using namespace std;
int main()
{
? ? int *p3=new int[5];? ? ? ? //在堆區(qū)申請空間
? ? //輸入5名學生成績
? ? for(int j=0;j<5;j++)
? ? {
? ? ? ? cin>>p3[j];
? ? }
? ? //輸出
? ? for(int i=0;i<5;i++)
? ? {
? ? ? ? cout<<p3[i]<<" "<<endl;
? ? }
? ? //排序
? ? for(int k=1;k<5;k++)
? ? {
? ? ? ? for(int l=0;l<5-k;l++)
? ? ? ? {
? ? ? ? ? ? if(p3[l]>p3[l+1])
? ? ? ? ? ? {
? ? ? ? ? ? ? ? int temp=p3[l];
? ? ? ? ? ? ? ? p3[l]=p3[l+1];
? ? ? ? ? ? ? ? p3[l+1]=temp;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? //輸出
? ? for(int o=0;o<5;o++)
? ? {
? ? ? ? cout<<"p3[o]="<<p3[o]<<endl;
? ? }
? ? //釋放內(nèi)存空間
? ? delete [] p3;
? ? p3 = nullptr;
? ? return 0;
}
2.3 new\delete與malloc\free的區(qū)別(筆試面試題)
1> new申請空間時,可以給堆區(qū)空間進行初始化,而malloc申請時不能進行初始化
2> new\delete是關(guān)鍵字,而malloc\free是庫函數(shù)
3> new申請空間時以數(shù)據(jù)類型為單位,而malloc申請空間時以字節(jié)為單位
4> new申請的空間返回的結(jié)果申請類型的指針,而malloc申請空間時返回void*類型,需要進行強轉(zhuǎn)后使用
5> new申請空間時會調(diào)用構(gòu)造函數(shù),malloc不會(后期講)
6> delete釋放空間時,會調(diào)用析構(gòu)函數(shù),free不會(后期講)
7> new、delete申請釋放空間時,區(qū)分單個還是連續(xù)空間,而malloc不區(qū)分
三、C++對C的函數(shù)部分的擴充
3.1 函數(shù)重載
1> 在C語言中,同一作用域下不允許定義多個同名的函數(shù),對于功能類似,但是只有數(shù)據(jù)類型不同的函數(shù),也要定義多個不同名的函數(shù),調(diào)用起來比較麻煩
2> C++中支持函數(shù)重載,即:在同一作用域下,可以定義多個同名的函數(shù),但是要求參數(shù)列表必須不同
3> 所謂函數(shù)重載,是靜態(tài)多態(tài)的一種,能夠做到“一名多用”
4> 函數(shù)重載的要求:
1、函數(shù)名相同
2、形參列表必須不同:可以是參數(shù)個數(shù)不同、參數(shù)類型不同
3、作用域也要相同
4、跟返回值沒有關(guān)系
5> 調(diào)用:當調(diào)用函數(shù)時,系統(tǒng)會根據(jù)傳遞的實參類型,自動匹配相應的重載函數(shù)
#include <iostream>
using namespace std;
//定義函數(shù)求兩個數(shù)據(jù)的和
int sum(int m, int n)? ? //sumii
{
? ? return m+n;
}
//求兩個小數(shù)的和
double sum(double m, double n) //sumdd
{
? ? return m+n;
}
//求兩個字符串的和
string sum(string m, string n)
{
? ? return m+n;
}
//定義求三個整數(shù)的和
int sum(int m, int n, int k) //sumiii
{
? ? return m+n+k;
}
int main()
{
? ? cout << sum(2,5) << endl;? ? ? ? ? ? //7 調(diào)用第一個函數(shù)
? ? cout << sum(2.3,5.2) << endl;? ? ? //7.5? 調(diào)用第二個函數(shù)
? ? cout << sum("hello ","world") << endl;? ? ? //hello world? 調(diào)用第三個函數(shù)
? ? return 0;
}
練習:使用函數(shù)重載完成求兩個整數(shù)的最大值、兩個小數(shù)的最大值、三個整數(shù)的最大值、兩個字符串的最大值,并完成調(diào)用(my_max)
#include <iostream>
using namespace std;
int my_max(int a, int b)
{
? ? if(a > b)
? ? {
? ? ? ? return a;
? ? }
? ? else
? ? {
? ? ? ? return b;
? ? }
}
int my_max(double a, double b)
{
? ? if(a > b)
? ? {
? ? ? ? return a;
? ? }
? ? else
? ? {
? ? ? ? return b;
? ? }
}
int my_max(int a, int b, int c)
{
? ? if(a > b && a > c)
? ? {
? ? ? ? return a;
? ? }
? ? else if(b > a && b > c)
? ? {
? ? ? ? return b;
? ? }
? ? else if(c > a && c > b)
? ? {
? ? ? ? return c;
? ? }
? ? return 0;
}
string my_max(string s1, string s2)
{
? ? if(s1 > s2)
? ? {
? ? ? ? return s1;
? ? }
? ? else
? ? {
? ? ? ? return s2;
? ? }
}
double sum(double a, int b)
{
? ? return a+b;
}
int main()
{
? ? cout<<my_max(3, 5)<<endl;
? ? my_max(2.3, 4.5);
? ? my_max(1, 2, 3);
? ? my_max("hello", "world");
? ? return 0;
}
3.2 函數(shù)默認參數(shù)
1> C語言中定義函數(shù)時,不允許設置默認參數(shù),函數(shù)形參的值,必須全部由實參進行傳遞后使用,實參的個數(shù)必須跟形參個數(shù)保持一致
2> C++定義函數(shù)時,允許給定默認參數(shù),即:如果該參數(shù)有實參進行傳遞,則使用實參傳遞進來的值進行使用,如果實參沒有對該參數(shù)進行傳遞,則使用默認參數(shù)
3> 默認參數(shù)的設置原則:靠右原則,只有右側(cè)的形形參設置了默認參數(shù)后,左側(cè)的形參才能設置默認參數(shù),否則報錯,原因是,函數(shù)實參向形參傳遞時是靠左原則
4> 當函數(shù)默認參數(shù)跟函數(shù)重載同時出現(xiàn)時,可以定義重載參數(shù)個數(shù)小于帶默認參數(shù)的函數(shù),但是,調(diào)用時會出現(xiàn)混亂情況
5> 當主調(diào)函數(shù)寫在被調(diào)函數(shù)定義之前時,需要對對被調(diào)函數(shù)進行函數(shù)聲明,函數(shù)的默認參數(shù),寫在函數(shù)聲明部分,函數(shù)定義部分就不需要加默認參數(shù)了
#include <iostream>
using namespace std;
int sum(int m = 50, int n=100, int k =200 );//對函數(shù)進行聲明
//當有函數(shù)進行設置默認參數(shù)時,再定義參數(shù)個數(shù)小于上述函數(shù)時,需要注意,是否重復,如果重復,
//定義時,沒有問題,但是調(diào)用該函數(shù)時,會出現(xiàn)混亂情況
int sum(int a, int b)
{
? ? return a+b;
}
int main()
{
? ? cout << sum(1,2,3) << endl;? ? ? ? ? //6? 此時,形參的值全部都由實參進行傳遞
? ? //cout << sum(1,2) << endl;? ? ? ? ? ? //203
? ? cout<<sum(1)<<endl;? ? ? ? ? ? ? ? ? //301
? ? cout<<sum()<<endl;? ? ? ? ? ? ? ? ? //350
? ? return 0;
}
//被調(diào)函數(shù)的定義
int sum(int m , int n, int k? )
{
? ? return m+n+k;
}
3.3 啞元
1> 在C++中的函數(shù)中,允許將函數(shù)參數(shù)設置成啞元,即某個形參只有類型名,沒有形參名,在函數(shù)體內(nèi)也不使用該形參
2> 作用:啞元參數(shù)只起到占位作用,沒有實質(zhì)性的用途
3> 使用場景
1、在進行程序代碼優(yōu)化時,可能某個函數(shù)的某幾個參數(shù)被優(yōu)化掉了,但是,該函數(shù)已經(jīng)在程序中調(diào)用多次,那么,此時就可以將這些參數(shù)設置成啞元,只起到占位作用,函數(shù)體內(nèi)無需使用
#include <iostream>
using namespace std;
//將第二個設置成啞元,只起到占位作用
int sum(int m, int, int k)
{
? ? return m+k;
}
int main()
{
? ? cout << sum(2,3,5) << endl;? ? ? ? ? //10
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? cout << sum(2,3,5) << endl;
? ? return 0;
}
2、在運算符重載時,進行區(qū)分自增自減運算符的前置和后置時,必須使用啞元完成(后期講)
3.4 內(nèi)聯(lián)函數(shù)(inline)
1> C++中,允許定義內(nèi)聯(lián)函數(shù),內(nèi)聯(lián)函數(shù)會建議編譯器在編譯程序的時候,將內(nèi)聯(lián)函數(shù)在調(diào)用處進行展開,運行時直接執(zhí)行函數(shù)體內(nèi)容,提高函數(shù)調(diào)用效率
2> 使用要求:要求函數(shù)體調(diào)用頻繁,并且函數(shù)體內(nèi)容較小,遞歸函數(shù)不允許定義成內(nèi)聯(lián)函數(shù)
3> 內(nèi)聯(lián)函數(shù)定義格式:在定義函數(shù)前加關(guān)鍵字inline即可
#include <iostream>
using namespace std;
//定義一個內(nèi)聯(lián)函數(shù)
inline int sum(int m, int n)
{
? ? return m+n;
}
int main()
{
? ? cout<<sum(1,2)<<endl;
? ? return 0;
}
4> 有參宏和內(nèi)聯(lián)函數(shù)的區(qū)別
1、本質(zhì)的區(qū)別:有參宏是宏替換,內(nèi)聯(lián)函數(shù)是函數(shù)調(diào)用
2、替換時機:有參宏替換發(fā)生在預處理階段,內(nèi)聯(lián)函數(shù)替換發(fā)生在編譯階段
#include <iostream>
using namespace std;
#define MAX(x,y) x>y?x:y? ? ? ? ? ? ? ? //定義有參宏
//定義一個內(nèi)聯(lián)函數(shù)
inline int my_max(int x, int y)
{
? ? return x>y?x:y;
}
int main()
{
? ? int a = 3;
? ? int b = 2;
? ? int c;
? ? c = MAX(a++,b++);? ? ? //a++ > b++? a++:b++;? ===> 3>2?4
? ? cout<<"a = "<<a<<"? b = "<<b<<"? c = "<<c<<endl;? ? ? ? ? //5? 3? 4
? ? a = 3;
? ? b = 2;
? ? c = my_max(a++, b++);? ? //my_max(3,2)
? ? cout<<"a = "<<a<<"? b = "<<b<<"? c = "<<c<<endl;? ? ? ? // 4? 3? 3
? ? return 0;
}
四、C++對結(jié)構(gòu)體的擴充
1> C語言中的結(jié)構(gòu)體,僅僅只是屬性(變量)的聚合體,不允許在結(jié)構(gòu)體中定義函數(shù),如果想要定義函數(shù),需要使用函數(shù)指針,完成函數(shù)回調(diào)
2> C++中的結(jié)構(gòu)體內(nèi)可以包羅萬象,既可以封裝屬性、也可以封裝函數(shù)、還可以封裝一個結(jié)構(gòu)體。。。
3> C++中的結(jié)構(gòu)體在定義屬性時,可以直接給定初始值,而C語言中不行
4> C++中的結(jié)構(gòu)體在定義結(jié)構(gòu)體變量時,可以不用加關(guān)鍵字struct,而C語言中不可以
5> C++中的結(jié)構(gòu)體可以有訪問權(quán)限控制,C語言中的結(jié)構(gòu)體沒有訪問權(quán)限控制
6> C++中的結(jié)構(gòu)體可以被繼承,C語言中的結(jié)構(gòu)體不可以
#include <iostream>
using namespace std;
//定義一個人的結(jié)構(gòu)體
struct Person
{
public:
? ? string name = "zhangsan";
private:
? ? int age = 0;
protected:
? ? double height = 1;
public:
? ? //在結(jié)構(gòu)體中封裝函數(shù)
? ? void show()
? ? {
? ? ? ? cout<<"name = "<<name<<"? age = "<<age<<"? height = "<<height<<endl;
? ? }
};
//定義一個老板結(jié)構(gòu)體,繼承自人這個結(jié)構(gòu)體
struct Boss:public Person
{
? ? int money = 100000;
};
int main()
{
? ? struct Person p1;
? ? p1.show();
? ? //cout<<p1.age<<endl;? ? //私有屬性不能被訪問
? ? cout<<p1.name<<endl;? ? //公共成員,外界可以直接使用
? ? //使用boos結(jié)構(gòu)體定義變量
? ? Boss b;
? ? b.show();
? ? b.money = 2000;
? ? return 0;
}
總結(jié):
①引用,本質(zhì)是什么?
②內(nèi)存申請以釋放,在c語言中有什么類的
③重載,是c++的一大特色。需要重點學習、復習、再學習、再復習