2020-02-15 C++核心編程04-基本框架

4.5.3遞增運(yùn)算符重載

作用:通過(guò)重載遞增運(yùn)算符,實(shí)現(xiàn)自己的整形數(shù)據(jù)

1.前置++

2.后置++(重載時(shí)引入占位參數(shù)int,用以告知編輯器為后置遞增)

總結(jié):前置遞增返回引用,后置遞增返回值

示例:

//自定義整型

class MyInteger

{

friend ostream &operator <<(ostream &os, MyInteger myint);

public:

MyInteger()

{

m_Num = 0;

}

//重載前置++運(yùn)算符

//返回引用是為了一直對(duì)一個(gè)數(shù)據(jù)進(jìn)行遞增操作

MyInteger& operator++()

{

++m_Num;

return *this;

}

//重載后置++運(yùn)算符

//int代表占位參數(shù),用于區(qū)分前置和后置遞增

//一定要返回值,因?yàn)榉祷鼐植繉?duì)象的引用是非法操作

//先返回,后++

MyInteger operator++(int )

{

MyInteger temp = *this;//記錄當(dāng)前本身的值

++m_Num;

return temp;

}

private:

int m_Num;

};

ostream &operator <<(ostream &os, MyInteger myint)

{

os << myint.m_Num;

return os;

}

void test01()

{

MyInteger myint;

cout <<++myint << endl;

cout << myint << endl;

}

void test02()

{

MyInteger myint;

cout << myint++ << endl;

cout << myint << endl;

}

4.5.4賦值運(yùn)算符重載

C++至少給一個(gè)類(lèi)添加4個(gè)函數(shù):

1.默認(rèn)構(gòu)造函數(shù)(無(wú)參,函數(shù)體為空)

2.默認(rèn)析構(gòu)函數(shù)(無(wú)參,函數(shù)體為空)

3.默認(rèn)拷貝構(gòu)造函數(shù),對(duì)屬性進(jìn)行值拷貝;

4.賦值運(yùn)算符operator=,對(duì)屬性進(jìn)行值拷貝

如果類(lèi)中有屬性指向堆區(qū),做賦值操作時(shí)也會(huì)出現(xiàn)深淺拷貝問(wèn)題;

淺拷貝:堆區(qū)內(nèi)存重復(fù)釋放,程序崩潰;

解決方案:利用深拷貝,解決淺拷貝帶來(lái)的問(wèn)題;

示例:

class Person

{

public:

Person(int age)

{

m_Age = new int(age);

cout << "Person(int)" << endl;

}

//注意:返回的是引用,才能返回對(duì)象自身

Person& operator=(const Person &p)

{

//m_Age = p.m_Age;//編譯器提供的淺拷貝

//應(yīng)該先判斷是否有屬性在堆區(qū),如果有,先釋放干凈

if (m_Age != NULL)

{

delete m_Age;

m_Age = NULL;

}

//然后再深拷貝

m_Age = new int(*p.m_Age);

return *this;

}

~Person()

{

if (m_Age != NULL)

{

delete m_Age;

m_Age = NULL;

}

cout << "~Person()" << endl;

}

//private:

int *m_Age;

};

4.5.5關(guān)系運(yùn)算符重載

1.推薦:友元函數(shù)的形式重載

2.也可成員函數(shù)形式重載

4.5.6函數(shù)調(diào)用運(yùn)算符重載

1.函數(shù)調(diào)用運(yùn)算符()也可以重載;

2.由于重載后使用方式非常像函數(shù)調(diào)用,因此稱(chēng)為仿函數(shù);

3.仿函數(shù)沒(méi)有固定寫(xiě)法,非常靈活;

補(bǔ)充:不想創(chuàng)建一個(gè)對(duì)象時(shí),可使用匿名函數(shù)對(duì)象;

示例:

//打印輸出類(lèi)

class MyPrint

{

public:

void operator()(string test)

{

cout << test << endl;

}

};

//仿函數(shù)非常靈活,沒(méi)有固定寫(xiě)法

class MyAdd

{

public:

int operator()(int a, int b)

{

return a + b;

}

};

void test01()

{

MyPrint myp;

myp("lalalala");//由于使用起來(lái)非常類(lèi)似于函數(shù)調(diào)用,因此稱(chēng)為仿函數(shù)

}

void test02()

{

MyAdd myadd;

cout<<myadd(5, 9)<<endl;

//匿名函數(shù)對(duì)象

cout << MyAdd()(10, 10) << endl;

}

4.6繼承

4.6.1繼承基本語(yǔ)法

繼承時(shí)面向?qū)ο笕筇匦灾唬?/p>

利用繼承技術(shù),可以減少重復(fù)代碼;

語(yǔ)法:class 子類(lèi)(派生類(lèi)) : 繼承方式? 父類(lèi)(基類(lèi))

4.6.2繼承方式

共三種:

1.公共繼承

2.保護(hù)繼承

3.私有繼承


4.6.3繼承中的對(duì)象模型

如何使用工具查看vs中的對(duì)象模型:

利用開(kāi)發(fā)人員命令提示工具查看對(duì)象模型

1.跳轉(zhuǎn)盤(pán)符? D:

2.跳轉(zhuǎn)文件路徑 cd ..具體路徑下

3.查看命令

cl /d1 reportSingleClassLayout 類(lèi)名 文件名(.cpp)

示例:

class Base

{

public:

int m_A;

protected:

int m_B;

private:

int m_C;

};

class Son

:public Base

{

public:

int m_D;

};

void test01()

{

//父類(lèi)中所有非靜態(tài)成員屬性都會(huì)被子類(lèi)繼承下去

//父類(lèi)中私有成員屬性 是被編譯器隱藏了

//因此是訪問(wèn)不到,但是確實(shí)被繼承下去了

cout << "sizeof(Son)=" << sizeof(Son) << endl;

}

注意:父類(lèi)中的私有成員也被子類(lèi)繼承了,只是訪問(wèn)不到


4.6.4繼承中的構(gòu)造和析構(gòu)順序

先調(diào)用父類(lèi)構(gòu)造函數(shù),再調(diào)用子類(lèi)構(gòu)造函數(shù);

析構(gòu)順序與構(gòu)造相反;


4.6.5繼承同名成員處理方式

1.訪問(wèn)子類(lèi)同名成員,直接訪問(wèn)即可;

2.訪問(wèn)父類(lèi)同名成員,需要加作用域;

示例:

class Base

{

public:

void func()

{

cout << "Base::func()" << endl;

}

void func(int a)

{

cout << "Base::func(int)" << endl;

}

};

class Son

:public Base

{

public:

void func()

{

cout << "Son::func()" << endl;

}

};

void test03()

{

Son s;

//如果子類(lèi)中出現(xiàn)和父類(lèi)同名的成員函數(shù)

//子類(lèi)的同名成員會(huì)隱藏掉父類(lèi)中所有同名成員函數(shù)

//“所有”是指只要函數(shù)名相同,哪怕參數(shù)不同

//如果想訪問(wèn)到父類(lèi)中被隱藏的同名成員函數(shù),需要加作用域

//s.func(100);//error

s.Base::func(100);

}

總結(jié):

1.子類(lèi)對(duì)象可以直接訪問(wèn)到子類(lèi)中的同名成員;

2.子類(lèi)對(duì)象加作用域可以訪問(wèn)到父類(lèi)同名成員;

3.當(dāng)父類(lèi)和子類(lèi)擁有同名的成員函數(shù),子類(lèi)會(huì)隱藏父類(lèi)中同名成員函數(shù),加作用域可以訪問(wèn)到父類(lèi)中的同名成員函數(shù);


4.6.6繼承同名靜態(tài)成員處理方式

靜態(tài)成員和非靜態(tài)成員出現(xiàn)同名,處理方式一致;

1.訪問(wèn)子類(lèi)同名成員,直接訪問(wèn)即可;

2.訪問(wèn)父類(lèi)同名成員,需要加作用域;

注意:靜態(tài)成員可以通過(guò)類(lèi)名訪問(wèn);

示例:

void test01()

? {

? //1.通過(guò)對(duì)象訪問(wèn)

? /*Son s;

? cout << "Base::m_A=" << s.Base::m_A << endl;

? cout << "Son::m_A=" << s.m_A << endl;*/

? //2.通過(guò)類(lèi)名訪問(wèn)

? cout << "Base::m_A=" << Base::m_A << endl;

? cout << "Son::m_A=" << Son::m_A << endl;

? //第一個(gè)::代表通過(guò)類(lèi)名方式訪問(wèn)?

? //第二個(gè)::代表訪問(wèn)父類(lèi)作用域下

? cout << "Base::m_A=" << Son::Base::m_A << endl;

? }

? void test02()

? {

? //1.通過(guò)對(duì)象訪問(wèn)

? Son s;

? s.func();

? s.Base::func();

? //2.通過(guò)類(lèi)名訪問(wèn)

? Son::func();

? Son::Base::func();

? }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容