詳解C++之函式過載
函式過載本質
c++中通過函式名和函式確定一個函式
所以相同的函式名,不同引數也是可以的
不同於c語言,c語言沒有函式過載,函式的本質地址就是函式名
函式過載發生在同一個作用域內
類中的過載
建構函式過載
普通成員函式過載
靜態成員函式過載
全域性函式、靜態成員函式、普通成員函式可以發生過載嗎?
本質就是函式名和函式引數不同,並且發生在同一個作用域
靜態函式和普通成員函式是可以的
全域性函式作用域在全域性作用域,所以不可以
問題1:當父類的成員函式和子類的成員函式相等,會發生過載嗎?
本質還是上面說的,因為父類和子類的作用域不在同一個
看一段程式碼
#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
這個函式現在只存在一個,那就是void print(int a)
,如果想呼叫父類的就要顯示指定child_test2->father::print()
;
問題2,子類可以重寫父類的函式嗎,或者說定義相同的?
看程式碼
#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; }
可見是可以定義相同的函式,並重寫的
問題3,當全域性運算子過載遇上類中的運算子過載,優先順序是什麼
#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)
類中的運算子過載優先順序大於全域性
當複製相容遇上全域性過載呢?
#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)
"
僅僅變化了,全域性的函式引數型別,正常來說類中和全域性的==都是可以的,但是當類中的需要一個預設的轉換,子類到父類,全域性的是直接型別就對的上的,編譯器就優先使用全域性的
說到運算子過載,我們現在定義函式實現類的功能有三種選擇:成員函式,全域性函式,全域性函式+友元函式
1.看是否需要虛擬函式,如果需要虛擬函式,那麼肯定是類的成員函式
2.看是否定義的是<<或者>>運算子,我們都知道列印輸出是全域性<<,但是為什麼呢,看一下實際的原型針對String
而言ostream& operator<<(ostream& output,const String& string)
我們使用的時候就是 std::cout << "haha
";
如果定義為類中的就是ostream& operator<<(ostream& output)
使用起來就是 "haha"<<"std::cout"
看出差別了吧,如果定義在類中使用起來就很彆扭,繼續上面的結果,如果是<<或者>>運算子,然後如果需要訪問private域,那麼就把全域性函式變為類對應的友元函式
3.當需要對左邊的引數進行型別轉換,需要定義全域性函式,因為類中操作符函式,左邊的就是類本身,如果需要訪問private域,那麼就把全域性函式變為類對應的友元函式
4.其他情況為類的成員函式
以上就是詳解C++之函式過載的詳細內容,更多關於c++之函式過載的資料請關注我們其它相關文章!