C++的函數重載實現原理


C++的函數重載實現原理

1.    什么是函數重載?
        函數重載是指在同一作用域內,可以有一組具有相同函數名,不同參數列表(參數個數、類型、順序)的函數,這組函數被稱為重載函數。重載函數通常用來聲明一組功能相似的函數,這樣做減少了函數名的數量,避免了名字空間的污染,對於程序的可讀性有很大的好處。


二、為什么要用函數重載
在我們之前學習的C中,我們對一個功能函數要實現不同類型的調用時,就必須得取不同的名稱。如果調用的非常的多,就必須得起好多的名字,這樣就大大增加了工作量,所以在C++中,我們就考慮到了函數重載。

三、 C++函數重載如何實現?
    在C++的底層,有重命名機制,比如下面這個函數。

    實現一個加法函數,可以對int型、double型、long型進行加法運算。在C++中,我們可以這樣做:

#include<iostream>
using namespace std;
int Add(int left, int right)
{
return left + right;
}

double Add(double left, double right)
{
return left + right;
}

long Add(long left, long right)
{
return left + right;
}

int main()
{
Add(10, 10);
Add(10.0, 10.0);
Add(10L, 10L);
return 0;
}
    通過上面代碼的實現,可以根據具體的Add()的參數去調用對應的函數。

底層的重命名機制將Add函數根據參數的個數,參數的類型,返回值的類型都做了重新命名。那么借助函數重載,一個函數就有多種命名機制。 

在C++調用約定(_cdecl 調用約定)中Add函數在底層被解析為:


"int __cdecl Add(int,int)" (?Add@@YAHHH@Z)
"double __cdecl Add(double,double)" (?Add@@YANNN@Z)
"long __cdecl Add(long,long)" (?Add@@YAJJJ@Z)
在C++ 程序中調用被 C 編譯器編譯后的函數,為什么要加 extern “C”聲明? 
(1)C++中可以通過在函數聲明前加 extern "C" 將一個函數按照 C 語言的風格來進行編譯。
(2)C++語言支持函數重載。而C不支持函數重載。 

(3)函數在C中和C++中編譯過的函數名字是不一樣的。加上extern”C”是說明是說明C已經編譯過的。 

        C++想要調用已經編譯過的C函數,由於編譯過的名字不同,是不能直接調用的,所以C++加extern“C”生命來解決這個問題。 

例如:假設某個函數的原型為: void foo(int x, int y);該函數被C 編譯器編譯后在庫中的名字為_foo, 而C++ 編譯器則會產生像_foo_int_int 之類的名字,加上extren”C”后,就相當於告訴編譯器,函數foo是個C編譯后的函數,在庫里應該找的是_foo,而不是_foo_int_int.

 下面兩個函數屬於函數重載嗎?
#include <iostream>
using namespace std;
int Add(short left, short right)
{
return left + right;
}

short Add(short left, short left)
{
return left + right;
}
這兩個函數只是返回值不同,並不構成函數重載。

2.    相關面試題
a) C語言為什么不支持函數重載
如上的三個Add函數,在C++中被解析為:

"int __cdecl Add(int,int)" (?Add@@YAHHH@Z)
"double __cdecl Add(double,double)" (?Add@@YANNN@Z)
"long __cdecl Add(long,long)" (?Add@@YAJJJ@Z)

在C語言中被解析為_Add,三個一樣,所以不能進行區分,因此C語言不支持函數重載
b) C++中函數重載底層是怎么處理的

底層的重命名機制將Add函數根據參數的個數,參數的類型,返回值的類型都做了重新命名。那么借助函數重載,一個函數就有多種命名機制。 

在C++調用約定(_cdecl 調用約定)中Add函數在底層被解析為:

"int __cdecl Add(int,int)" (?Add@@YAHHH@Z)
"double __cdecl Add(double,double)" (?Add@@YANNN@Z)
"long __cdecl Add(long,long)" (?Add@@YAJJJ@Z)
c) C++中能否將一個函數按照C的風格來編譯

C++中可以通過在函數聲明前加 extern "C" 將一個函數按照 C 語言的風格來進行編譯。


https://blog.csdn.net/fantian_/article/details/80719144


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM