網(wǎng)站設(shè)計(jì)公司種類推薦一個(gè)seo優(yōu)化軟件
這篇文章主要內(nèi)容是構(gòu)造函數(shù)的初始化列表以及運(yùn)算符重載在順序表中的簡(jiǎn)單應(yīng)用,運(yùn)算符重載實(shí)現(xiàn)自定義類型的流插入流提取。希望對(duì)大家有所幫助,點(diǎn)贊+收藏+評(píng)論,支持一下吧!
目錄
構(gòu)造函數(shù)進(jìn)階理解
?1.內(nèi)置類型成員在參數(shù)列表中的定義
2.自定義類型成員在參數(shù)列表中的定義
3.初始化列表解決的三大問(wèn)題
(1)類中的引用成員變量
?編輯
(2)const成員變量
(3)自定義類型成員沒(méi)有默認(rèn)構(gòu)造函數(shù)時(shí)的問(wèn)題
運(yùn)算符重載的應(yīng)用
(1)順序表中的運(yùn)算符重載
(2)自定義類型的流插入流提取
構(gòu)造函數(shù)進(jìn)階理解
在上一篇文章中,我們已經(jīng)了解過(guò)構(gòu)造函數(shù)的作用:初始化對(duì)象。
注意,構(gòu)造函數(shù)僅僅說(shuō)是初始化對(duì)象,那么在初始化前一定有為對(duì)象分配內(nèi)存空間,即成員變量的定義。什么時(shí)候完成成員變量的定義呢?那就是構(gòu)造函數(shù)內(nèi)部的初始化列表。
下面給出初始化列表的語(yǔ)法規(guī)則:
class A//類A
{
public:A(){cout<<"調(diào)用A的默認(rèn)構(gòu)造 A()"<<endl;_a=i;}A(int i){cout << "調(diào)用A的帶參構(gòu)造 A(int)" << endl;_a = i;}
private:int _a;
};
class Date//類Date
{
public:Date(int year = 1, int month = 1, int day = 1)//構(gòu)造函數(shù):_year(year),//構(gòu)造函數(shù)的初始化列表(為成員變量分配空間)_month(month),_day(day),a(){//構(gòu)造函數(shù)函數(shù)體}
private://成員變量的聲明int _year;//內(nèi)置類型成員int _month;int _day;A a;//自定義類型成員
};
初始化列表是構(gòu)造函數(shù)不可缺少的,就算不手動(dòng)寫編譯器也會(huì)默認(rèn)添加。默認(rèn)添加的初始化列表為內(nèi)置類型分配空間,但不指定值(隨機(jī)值)。對(duì)自定義類型成員會(huì)調(diào)用自定義類型的默認(rèn)構(gòu)造函數(shù)。
public:Date(int year = 1, int month = 1, int day = 1)//構(gòu)造函數(shù)/*:_year(), //編譯器默認(rèn)添加,會(huì)為成員分配內(nèi)存空間,是隨機(jī)值_month(),_day(),a()*/ //對(duì)自定義類型會(huì)調(diào)用自定義類型的默認(rèn)構(gòu)造函數(shù){}
?1.內(nèi)置類型成員在參數(shù)列表中的定義
此時(shí)上面的構(gòu)造函數(shù)未手動(dòng)添加初始化列表,這時(shí)創(chuàng)建一個(gè)對(duì)象
Date d1;
d1.Print();
打印d1的內(nèi)置類型成員變量。
?是隨機(jī)值,因?yàn)?span style="background-color:#ff9900;">默認(rèn)初始化列表只為內(nèi)置類型成員變量分配了內(nèi)存空間,并沒(méi)有給成員變量賦值。
此時(shí)賦值操作既可以在手動(dòng)添加的初始化列表中完成,也可以在函數(shù)體中完成賦值。
(1).手動(dòng)添加的初始化列表中完成賦值
Date(int year = 1, int month = 1, int day = 1)//構(gòu)造函數(shù):_year(year),_month(month),_day(day){}
Date d1;
d1.Print();
運(yùn)行結(jié)果:
?(2).函數(shù)體內(nèi)完成賦值
public:Date(int year = 1, int month = 1, int day = 1)//構(gòu)造函數(shù)/* :_year(),_month(),_day()*/ //默認(rèn)參數(shù)列表{_year = year;_month = month;_day = day;}
Date d1;
d1.Print();
運(yùn)行結(jié)果:
總結(jié):內(nèi)置類型成員變量的定義(分配內(nèi)存空間)只能在初始化列表中一次性完成,不管寫不寫都會(huì)有這個(gè)過(guò)程,手動(dòng)寫可以順便在定義時(shí)賦值。不寫編譯器的默認(rèn)參數(shù)列表會(huì)將成員變量定義為隨機(jī)值,之后再函數(shù)體中再次賦想要的值。?
2.自定義類型成員在參數(shù)列表中的定義
當(dāng)我們不手動(dòng)添加初始化列表,默認(rèn)的初始化列表會(huì)調(diào)用自定義類型成員的默認(rèn)構(gòu)造函數(shù)
例如:當(dāng)構(gòu)造函數(shù)是這樣時(shí)
Date(int year = 1, int month = 1, int day = 1)//構(gòu)造函數(shù)//:_year(),//默認(rèn)初始化列表//_month(),//_day(),//a() 默認(rèn)構(gòu)造函數(shù)的調(diào)用{//構(gòu)造函數(shù)函數(shù)體}
Date d1;
運(yùn)行結(jié)果:?
?
?當(dāng)我們手動(dòng)寫初始化列表時(shí),就可以選擇性的調(diào)用自定義類型的構(gòu)造函數(shù),可以是帶參的,也可以是默認(rèn)構(gòu)造函數(shù)。
Date(int year = 1, int month = 1, int day = 1)//構(gòu)造函數(shù):_year(year),//默認(rèn)初始化列表_month(month),_day(day),a(2) //選擇調(diào)用帶參構(gòu)造函數(shù)
此時(shí)
Date d1;
運(yùn)行結(jié)果?
?
?總結(jié):默認(rèn)構(gòu)造函數(shù)對(duì)自定義類型自動(dòng)調(diào)用自定義類型的默認(rèn)構(gòu)造方法本質(zhì)是默認(rèn)構(gòu)造函數(shù)的默認(rèn)初始化列表調(diào)用自定義類型的默認(rèn)構(gòu)造方法。只要構(gòu)造方法使用默認(rèn)初始化列表,對(duì)自定義類型就會(huì)調(diào)用它的默認(rèn)構(gòu)造方法。反之,手動(dòng)添加初始化列表就可以選擇性的調(diào)用自定義類型的構(gòu)造方法。
3.初始化列表解決的三大問(wèn)題
(1)類中的引用成員變量
引用在定義的時(shí)候必須初始化,否則會(huì)出現(xiàn)編譯錯(cuò)誤,詳見(jiàn)重生之我要學(xué)C++第二天_無(wú)極太族的博客-CSDN博客
類中的成員都是在初始化列表中定義的,如果成員有引用類型就必須在初始化列表中初始化。
#include<iostream>
using namespace std;
class A
{
public :A(int a){_a = a;//初始化}
private:int& _a;
};
int main()
{int tmp = 2;A a(tmp);return 0;
}
此時(shí),引用_a的定義在默認(rèn)初始化列表中已經(jīng)完成,在構(gòu)造函數(shù)函數(shù)體中在賦值初始化會(huì)導(dǎo)致編譯錯(cuò)誤(定義處未初始化)。
解決方案:在構(gòu)造函數(shù)中手動(dòng)添加初始化列表,在初始化列表中定義和初始化一并進(jìn)行。
A(int a)
:
_a(a)
{}
(2)const成員變量
const成員變量容易出問(wèn)題和引用的原理相同。都是定義處必須初始化。
(3)自定義類型成員沒(méi)有默認(rèn)構(gòu)造函數(shù)時(shí)的問(wèn)題
我們知道,構(gòu)造函數(shù)不寫初始化列表時(shí),默認(rèn)初始化列表會(huì)調(diào)用自定義類型的默認(rèn)構(gòu)造函數(shù)
默認(rèn)構(gòu)造函數(shù):
?詳見(jiàn):重生之我要學(xué)C++第四天_無(wú)極太族的博客-CSDN博客
但是如果此時(shí)這個(gè)自定義類型沒(méi)有默認(rèn)構(gòu)造方法,會(huì)出現(xiàn)編譯錯(cuò)誤。
這時(shí)候就必須手動(dòng)添加參數(shù)列表,選擇性的調(diào)用自定義類型具有的構(gòu)造方法。
運(yùn)算符重載的應(yīng)用
第四天我們學(xué)習(xí)了運(yùn)算符重載,在這里舉兩個(gè)例子讓讀者感受到運(yùn)算符重載的魅力!
(1)順序表中的運(yùn)算符重載
先寫一個(gè)簡(jiǎn)陋的順序表
#include<iostream>
using namespace std;
class Sequence
{
public:Sequence(){//初始化_a = (int*)malloc(4 * sizeof(int));_size = 0;_capcity = 4;}void Push(int x){//檢查容量:此處忽略_a[_size] = x;_size++;}void Print(){for (int i = 0; i < _size; i++){cout << _a[i] << " ";}}
private:int* _a;int _size;int _capcity;
};
int main()
{Sequence s;//創(chuàng)建順序表s.Push(1);//尾插三個(gè)數(shù)據(jù)s.Push(2);s.Push(3);//打印順序表s.Print();return 0;
}
我們可以在類內(nèi)部將[ ]重載一下
int& operator[](int i)
{return _a[i];
}
此時(shí),順序表內(nèi)的元素就可以像數(shù)組一樣訪問(wèn):
int main()
{Sequence s;//創(chuàng)建順序表s.Push(1);//尾插三個(gè)數(shù)據(jù)s.Push(2);s.Push(3);//打印順序表cout << s[0]<<s[1]<<s[2]<<endl;return 0;
}
重載[ ]后,可以讓順序表更加形象,大大增強(qiáng)了代碼的可讀性。?
(2)自定義類型的流插入流提取
用Date類來(lái)舉例
#include<iostream>
using namespace std;
class Date//類Date
{
public:Date(int year=1, int month=1, int day=1)//構(gòu)造函數(shù){_year = year;_month = month;_day = day;}void Print(){cout << _year << "年" << _month << "月" << _day << "天" << endl;}
private://成員變量的聲明int _year;//內(nèi)置類型成員int _month;int _day;
};
int main()
{Date d1(1,1,2);d1.Print();return 0;
}
可以使用Print函數(shù)來(lái)打印日期
?但是如果這樣也可以打印日期,是不是會(huì)覺(jué)得賞心悅目
cout<<d1<<endl;
下面我們就利用運(yùn)算符重載來(lái)實(shí)現(xiàn)這個(gè)想法。
#include<iostream>
using namespace std;class Date//類Date
{
public:friend ostream& operator<<(ostream& out, Date& d);//將此函數(shù)聲明為類Date的友元函數(shù)Date(int year=1, int month=1, int day=1)//構(gòu)造函數(shù){_year = year;_month = month;_day = day;}void Print(){cout << _year << "年" << _month << "月" << _day << "天" << endl;}
private://成員變量的聲明int _year;//內(nèi)置類型成員int _month;int _day;
};
ostream& operator<<(ostream& out, Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "天";return out;
}
int main()
{Date d1(1, 1, 2);cout << d1;return 0;
}
?運(yùn)行結(jié)果:
?這里cout是ostream類的對(duì)象,將運(yùn)算符重載寫為全局函數(shù)就可以調(diào)換cout對(duì)象和d對(duì)象的位置。使用友元函數(shù)使得在類外面的函數(shù)可以訪問(wèn)類的private成員。下篇文章會(huì)介紹友元函數(shù)。
今天的分享就到這里啦,如果對(duì)大家有用的話,希望程序猿們可以三連支持一下,會(huì)繼續(xù)分享知識(shí)!謝謝!