詳解C++之函數(shù)重載
函數(shù)重載本質(zhì)
c++中通過函數(shù)名和函數(shù)確定一個函數(shù)
所以相同的函數(shù)名,不同參數(shù)也是可以的
不同于c語言,c語言沒有函數(shù)重載,函數(shù)的本質(zhì)地址就是函數(shù)名
函數(shù)重載發(fā)生在同一個作用域內(nèi)
類中的重載
構(gòu)造函數(shù)重載
普通成員函數(shù)重載
靜態(tài)成員函數(shù)重載
全局函數(shù)、靜態(tài)成員函數(shù)、普通成員函數(shù)可以發(fā)生重載嗎?
本質(zhì)就是函數(shù)名和函數(shù)參數(shù)不同,并且發(fā)生在同一個作用域
靜態(tài)函數(shù)和普通成員函數(shù)是可以的
全局函數(shù)作用域在全局作用域,所以不可以
問題1:當父類的成員函數(shù)和子類的成員函數(shù)相等,會發(fā)生重載嗎?
本質(zhì)還是上面說的,因為父類和子類的作用域不在同一個
看一段代碼
#include <iostream> class father{ public: father() { std::cout << "father()" << std::endl; } void print() { std::cout << "father print" << std::endl; } }; class child : public father{ public: child() { std::cout << "child()" << std::endl; } void print(int a) { std::cout << "child print = " << a << std::endl; } }; int main(){ father* father_test = new father(); father_test->print(); //打印father print child* child_test2 = new child(); child_test2->print(); //編譯錯誤no matching function for call to 'child::print()' return 0; }
由打印輸出可得第一個打印屬于father正常輸出,沒問題,第二個打印是編譯錯誤,我們其實想訪問的是父類的print
,但是由于子類定義了print
,那么在子類的作用域中,print
這個函數(shù)現(xiàn)在只存在一個,那就是void print(int a)
,如果想調(diào)用父類的就要顯示指定child_test2->father::print()
;
問題2,子類可以重寫父類的函數(shù)嗎,或者說定義相同的?
看代碼
#include <iostream> class father{ public: father() { std::cout << "father()" << std::endl; } void print() { std::cout << "father print" << std::endl; } }; class child : public father{ public: child() { std::cout << "child()" << std::endl; } void print() { std::cout << "child print" << std::endl; } }; int main(){ father* father_test = new father(); father_test->print(); //打印father print child* child_test2 = new child(); child_test2->print(); //child print return 0; }
可見是可以定義相同的函數(shù),并重寫的
問題3,當全局運算符重載遇上類中的運算符重載,優(yōu)先級是什么
#include <iostream> class child; class father{ public: father() { std::cout << "father()" << std::endl; } bool operator==(const father& e) { std::cout << "void print(const father& e)" << std::endl; } }; bool operator==(const father& e1, const father& e2) { std::cout << "void print(const child& e1, const child& e2)" << std::endl; } class child : public father{ public: child() { std::cout << "child()" << std::endl; } }; int main(){ child child1_test; child child2_test; child1_test==child2_test; return 0; }
輸出為void print(const father& e)
類中的運算符重載優(yōu)先級大于全局
當復制兼容遇上全局重載呢?
#include <iostream> class child; class father{ public: father() { std::cout << "father()" << std::endl; } bool operator==(const father& e) { std::cout << "void print(const father& e)" << std::endl; } }; bool operator==(const child& e1, const child& e2) { std::cout << "void print(const child& e1, const child& e2)" << std::endl; } class child : public father{ public: child() { std::cout << "child()" << std::endl; } }; int main(){ child child1_test; child child2_test; child1_test==child2_test; return 0; }
打?。?void print(const child& e1, const child& e2)
"
僅僅變化了,全局的函數(shù)參數(shù)類型,正常來說類中和全局的==都是可以的,但是當類中的需要一個默認的轉(zhuǎn)換,子類到父類,全局的是直接類型就對的上的,編譯器就優(yōu)先使用全局的
說到運算符重載,我們現(xiàn)在定義函數(shù)實現(xiàn)類的功能有三種選擇:成員函數(shù),全局函數(shù),全局函數(shù)+友元函數(shù)
1.看是否需要虛函數(shù),如果需要虛函數(shù),那么肯定是類的成員函數(shù)
2.看是否定義的是<<或者>>運算符,我們都知道打印輸出是全局<<,但是為什么呢,看一下實際的原型針對String
而言ostream& operator<<(ostream& output, const String& string)
我們使用的時候就是 std::cout << "haha
";
如果定義為類中的就是ostream& operator<<(ostream& output)
使用起來就是 "haha"<<"std::cout"
看出差別了吧,如果定義在類中使用起來就很別扭,繼續(xù)上面的結(jié)果,如果是<<或者>>運算符,然后如果需要訪問private域,那么就把全局函數(shù)變?yōu)轭悓挠言瘮?shù)
3.當需要對左邊的參數(shù)進行類型轉(zhuǎn)換,需要定義全局函數(shù),因為類中操作符函數(shù),左邊的就是類本身,如果需要訪問private域,那么就把全局函數(shù)變?yōu)轭悓挠言瘮?shù)
4.其他情況為類的成員函數(shù)
以上就是詳解C++之函數(shù)重載的詳細內(nèi)容,更多關(guān)于c++之函數(shù)重載的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Qt實現(xiàn)SqlTableModel映射組件應用小結(jié)
在Qt中提供了QSqlTableModel模型類,它為開發(fā)者提供了一種直觀的方式來與數(shù)據(jù)庫表格進行交互,本文就來介紹一下Qt實現(xiàn)SqlTableModel映射組件應用小結(jié),感興趣的可以了解一下2023-12-12C++筆記-設置cout輸出數(shù)據(jù)的寬度和填充方式
這篇文章主要介紹了C++筆記-設置cout輸出數(shù)據(jù)的寬度和填充方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11