C++運(yùn)算符重載與多繼承及二義性詳解
1.類外運(yùn)算符重載
class Point { private: int x,y; public: // 系統(tǒng)C++源碼,大量使用此方式 :x(x), y(y) Point(int x, int y) :x(x), y(y) {} // set get 函數(shù) void setX(int x) { this->x = x; } void setY(int y) { this->y = y; } int getX() { return this->x; } int getY() { return this->y; } }; /*類外運(yùn)算符重載 * 在真實(shí)開(kāi)發(fā)過(guò)程中,基本上都是寫在類的里面的,外部是不能獲取內(nèi)部的私有成員的 * */ Point operator + (Point point1,Point point2){ int x = point1.getX() + point2.getX(); int y = point1.getY() + point2.getY(); Point res(x, y); return res; } int main(){ Point pointA(10,20); Point pointB(10,20); Point pointC=pointA+pointB; cout << pointC.getX() << " , " << pointC.getY() << endl; }
日志輸出:
20 , 40
兩個(gè)對(duì)象做+法運(yùn)算就是執(zhí)行了運(yùn)算符重載函數(shù)
2.類內(nèi)部運(yùn)算符號(hào)重載
class Point { private: int x,y; public: Point(){} // 系統(tǒng)C++源碼,大量使用此方式 :x(x), y(y) Point(int x, int y) :x(x), y(y) {} // set get 函數(shù) void setX(int x) { this->x = x; } void setY(int y) { this->y = y; } int getX() { return this->x; } int getY() { return this->y; } /* * 常量引用:不允許修改,只讀模式 * & 性能的提高,如果沒(méi)有& 運(yùn)行+ 構(gòu)建新的副本,會(huì)浪費(fèi)性能 * 如果增加了& 引用是給這塊內(nèi)存空間取一個(gè)別名而已 * */ Point operator + (const Point & point){ int x=this->x+point.x; int y=this->y+point.y; return Point(x,y); } Point operator - (const Point & point){ int x=this->x-point.x; int y=this->y-point.y; return Point(x,y); } void operator ++() { // ++對(duì)象 this->x = this->x + 1; this->y = this->y + 1; } void operator ++ (int) { // 對(duì)象++ this->x = this->x + 1; this->y = this->y + 1; } /*重載<< 輸出運(yùn)算符號(hào) * istream 輸入 系統(tǒng)的 * ostream 輸出 系統(tǒng)的 * */ /* friend void operator << (ostream & _START,Point &point){ _START << " 開(kāi)始輸出 " << point.x << " : " << point.y << " 結(jié)束了 " << endl; }*/ /*多個(gè)<< 連著寫 */ friend ostream & operator << (ostream & _START,Point &point){ _START << " 開(kāi)始輸出 " << point.x << " : " << point.y << " 結(jié)束了 " << endl; return _START; } // istream 輸入 系統(tǒng)的 friend istream & operator >> (istream & _START, Point & point) { // 接收用戶的輸入,把輸入的信息 _START >> point.x >> point.y; return _START; } }; int main(){ Point pointA(30,50); Point pointB(10,20); // Point pointC=pointA-pointB; ++pointA; // cout << pointA.getX() << " , " << pointA.getY() << endl; cout << pointA << pointB <<endl; // 多個(gè)的 Point pointC; cin >> pointC; // >> 是我們自己重載的哦 cout << "你輸入的是:" << pointC.getX() << endl; cout << "你輸入的是:" << pointC.getY() << endl; }
- 類內(nèi)部運(yùn)算符重載,允許訪問(wèn)私有變量
- 傳入的參數(shù)是常量引用,const 表示不可更改,& 可以提升性能,只會(huì)有一個(gè)變量別名,不加會(huì)拷貝一份,浪費(fèi)內(nèi)存。
- << >> 重載,需要加friend 友元函數(shù)來(lái)進(jìn)行重載
- ostream & _START:表示輸出
- istream & _START:表示輸入
3.[] 運(yùn)算符號(hào)重載
class ArrayClass { private: int size =0 ; // 大小 開(kāi)發(fā)過(guò)程中,給size賦默認(rèn)值,不然可能會(huì)出現(xiàn),無(wú)窮大的問(wèn)題 int * arrayValue; // 數(shù)組存放 int 類型的很多值 public: ArrayClass(){ /*指針類型必須分配空間*/ arrayValue= static_cast<int *>(malloc(sizeof(int *) * 10)); } void set(int index, int value) { arrayValue[index] = value; // []目前不是我的 size+=1; } int getSize() { // size成員的目標(biāo):是為了循環(huán)可以遍歷 return this->size; } // 運(yùn)算符重載 [index] int operator[](int index) { return this->arrayValue[index]; // 系統(tǒng)的 } }; // 輸出容器的內(nèi)容 void printfArryClass(ArrayClass arrayClass) { cout << arrayClass.getSize() << endl; for (int i = 0; i < arrayClass.getSize(); ++i) { cout << arrayClass[i] << endl; // []是我們自己的 重載符號(hào) } } int main(){ ArrayClass arrayClass; // 棧區(qū) 實(shí)例出來(lái)的對(duì)象,是在堆區(qū)了 arrayClass.set(0, 100); arrayClass.set(1, 200); arrayClass.set(2, 300); arrayClass.set(3, 400); arrayClass.set(4, 500); printfArryClass(arrayClass); }
4.c++繼承
class Person { public: char *name; int age; public: Person(char *name, int age) : name(name) { this->age = age; cout << "Person 構(gòu)造函數(shù)" << endl; } void print() { cout << this->name << " , " << this->age << endl; } }; class Student : public Person { private: char * course; public: Student(char * name, int age, char* course) : Person(name, age) , course(course) { cout << "Student 構(gòu)造函數(shù)" << endl; } void test() { cout << name << endl; cout << age << endl; print(); } };
- 默認(rèn)是 隱式代碼: : private Person
- 私有繼承:在子類里面是可以訪問(wèn)父類的成員,但是在類的外面不行
- 必須公開(kāi)繼承,才可以訪問(wèn)父類的成員
- 先執(zhí)行父類的構(gòu)造函數(shù),再執(zhí)行子類的構(gòu)造函數(shù)
5.多繼承
class BaseActivity1 { public: void onCreate() { cout << "BaseActivity1 onCreate" << endl; } void onStart() { cout << "BaseActivity1 onStart" << endl; } void show() { cout << "BaseActivity1 show" << endl; } }; class BaseActivity2 { public: void onCreate() { cout << "BaseActivity2 onCreate" << endl; } void onStart() { cout << "BaseActivity2 onStart" << endl; } void show() { cout << "BaseActivity2 show" << endl; } }; // 子類 繼承 二個(gè)父類 class MainActivity1 : public BaseActivity1, public BaseActivity2{ public: void onCreate() { cout << "MainActivity1 onCreate" << endl; } void onStart() { cout << "MainActivity1 onStart" << endl; } void showSonInfo() { cout << "MainActivity1 showSonInfo" << endl; } // void show() { // cout << "MainActivity1 show" << endl; //} }; int main(){ // 這個(gè)是優(yōu)先尋找子類的函數(shù),因?yàn)樘貏e明確,沒(méi)有問(wèn)題,還沒(méi)有產(chǎn)生歧義(二義性) MainActivity1 mainActivity1; // 子類 mainActivity1.onCreate(); mainActivity1.onStart(); mainActivity1.showSonInfo(); // 不明確,二義性,歧義 /*request for member ‘show' is ambiguous*/ // mainActivity1.show(); /*解決二義性 通過(guò).來(lái)引出父類 然后再調(diào)用*/ mainActivity1.BaseActivity3::show(); mainActivity1.BaseActivity2::show(); mainActivity1.BaseActivity1::show(); // 解決方案二: 子類上 重寫父類的show函數(shù) mainActivity1.show(); }
- c++ 允許多繼承,可能會(huì)出現(xiàn)二義性,原則上是盡量避免二義性
- 通過(guò)明確父類的方式解決二義性
- 通過(guò)子類重寫父類的方法規(guī)避二義性
6.通過(guò)虛繼承來(lái)解決二義性問(wèn)題
// 祖父類 class Object{ public: int number; void show() { cout << "Object show run..." << endl; } }; // 父類1 class BaseActivity1 : virtual public Object { }; // 父類2 class BaseActivity2 : virtual public Object { }; // 子類 class Son : public BaseActivity1, public BaseActivity2 { }; int main(){ Object object; BaseActivity1 baseActivity1; BaseActivity2 baseActivity2; Son son; object.number = 100; baseActivity1.number = 200; baseActivity2.number = 300; son.number = 400; object.show(); baseActivity1.show(); baseActivity2.show(); son.show(); cout << object.number << endl; cout << baseActivity1.number << endl; cout << baseActivity2.number << endl; cout << son.number << endl; }
- 如果沒(méi)有虛繼承,那么son對(duì)象訪問(wèn)number就會(huì)報(bào)二義性的問(wèn)題,同時(shí)訪問(wèn)show方法同樣存在二義性問(wèn)題
- 由于在繼承的時(shí)候添加了虛繼承,就能解決類似這樣的問(wèn)題,虛繼承的含義是:將通過(guò)繼承得來(lái)的number和show方法,放置在另外一個(gè)統(tǒng)一空間上,這樣子類再訪問(wèn)的時(shí)候就不會(huì)出現(xiàn)二義性的問(wèn)題了。
到此這篇關(guān)于C++運(yùn)算符重載與多繼承及二義性詳解的文章就介紹到這了,更多相關(guān)C++運(yùn)算符重載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++11?實(shí)現(xiàn)枚舉值到枚舉名的轉(zhuǎn)換問(wèn)題
這篇文章主要介紹了c++11?實(shí)現(xiàn)枚舉值到枚舉名的轉(zhuǎn)換,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03C語(yǔ)言詳解如何應(yīng)用模擬字符串和內(nèi)存函數(shù)
這篇文章主要介紹了C語(yǔ)言詳解如何應(yīng)用模擬字符串和內(nèi)存函數(shù),文章有點(diǎn)長(zhǎng),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02C語(yǔ)言數(shù)組實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言數(shù)組實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01C語(yǔ)言實(shí)例講解四大循環(huán)語(yǔ)句的使用
C語(yǔ)言有四大循環(huán)語(yǔ)句,他們之間可以進(jìn)行任意轉(zhuǎn)換。本文將首先對(duì)其語(yǔ)法進(jìn)行講解,然后通過(guò)一個(gè)實(shí)例用四種循環(huán)來(lái)實(shí)現(xiàn)。相信通過(guò)本文的學(xué)習(xí),大家都能夠?qū)語(yǔ)言循環(huán)語(yǔ)句有著熟練的掌握2022-05-05關(guān)于C++STL string類的介紹及模擬實(shí)現(xiàn)
這篇文章主要介紹了關(guān)于C++STL string類的介紹及模擬實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下面具體的文章內(nèi)容2021-09-09C語(yǔ)言靜態(tài)版通訊錄的設(shè)計(jì)與實(shí)現(xiàn)
靜態(tài)版通訊錄是一種簡(jiǎn)單的通訊錄實(shí)現(xiàn)方式,通過(guò)定義固定的數(shù)組大小來(lái)存儲(chǔ)聯(lián)系人信息。該方法不支持動(dòng)態(tài)增刪聯(lián)系人,但具有實(shí)現(xiàn)簡(jiǎn)單、易于理解的優(yōu)點(diǎn)。在程序設(shè)計(jì)中,需注意數(shù)組邊界溢出等問(wèn)題2023-04-04C++中?‘=default?’及‘?=delete?’的使用
這篇文章主要介紹了C++中?=default?及?=delete?使用,使用=default和=delete可以控制編譯器默認(rèn)函數(shù)體的使用,下面我們就來(lái)看看具體的室友方法吧,需要的朋友也可以參考一下2021-12-12C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器
這篇文章主要為大家詳細(xì)介紹了如何利用C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器,并支持軟硬解碼,支持音頻,支持錄像截圖,支持多路播放等,感興趣的可以了解下2024-01-01