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í)開發(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
兩個對象做+法運(yùn)算就是執(zhí)行了運(yùn)算符重載函數(shù)
2.類內(nèi)部運(yùn)算符號重載
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;
}
/*
* 常量引用:不允許修改,只讀模式
* & 性能的提高,如果沒有& 運(yùn)行+ 構(gòu)建新的副本,會浪費(fèi)性能
* 如果增加了& 引用是給這塊內(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;
}
/*重載<< 輸出運(yùn)算符號
* 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)部運(yùn)算符重載,允許訪問私有變量
- 傳入的參數(shù)是常量引用,const 表示不可更改,& 可以提升性能,只會有一個變量別名,不加會拷貝一份,浪費(fèi)內(nèi)存。
- << >> 重載,需要加friend 友元函數(shù)來進(jìn)行重載
- ostream & _START:表示輸出
- istream & _START:表示輸入
3.[] 運(yùn)算符號重載
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;
}
// 運(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; // []是我們自己的 重載符號
}
}
int main(){
ArrayClass arrayClass; // 棧區(qū) 實(shí)例出來的對象,是在堆區(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ù),因?yàn)樘貏e明確,沒有問題,還沒有產(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++運(yùn)算符重載與多繼承及二義性詳解的文章就介紹到這了,更多相關(guān)C++運(yùn)算符重載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解C++中對構(gòu)造函數(shù)和賦值運(yùn)算符的復(fù)制和移動操作
這篇文章主要介紹了C++中對構(gòu)造函數(shù)和賦值運(yùn)算符的復(fù)制和移動,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-01-01
C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù))
cJSON是一個超輕巧的JSON解析器,本文主要介紹了C/C++中CJSON的使用(創(chuàng)建與解析JSON數(shù)據(jù)),具有一定的參考價值,感興趣的可以了解一下2021-09-09
解析C++中的for循環(huán)以及基于范圍的for語句使用
這篇文章主要介紹了解析C++中的for循環(huán)以及基于范圍的for語句使用,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-01-01
C++實(shí)現(xiàn)多源最短路徑之Floyd算法示例
這篇文章主要介紹了C++實(shí)現(xiàn)多源最短路徑之Floyd算法,結(jié)合實(shí)例形式分析了多源最短路徑之Floyd算法的原理、實(shí)現(xiàn)方法及核心代碼,需要的朋友可以參考下2017-08-08

