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

