1. 程式人生 > >C++:名稱空間,函式過載與預設引數

C++:名稱空間,函式過載與預設引數

本篇部落格主要針對與c與c++不同的地方做以總結。

C++:在C的基礎上添加了一些新的特性
C++的學習主要分為以下幾個大的板塊。
- c
- 類 & 物件
- 繼承 & 多型
- 模板 & 泛型程式設計
- 異常處理
- C++庫 & STL

也就是說,之前我們所學過的c語言的所有知識在c++中仍然適用。

資料型別

  1. 內建型別
  2. 自定義型別:struct/class/enum/union

名稱空間

名稱空間域是隨c++標準引入的,相當於一個更加靈活的檔案域,可以用花括號把檔案的一部分括起來,並以關鍵字namespace開頭給它起一個名字。

namespace name1
{
    int a=10;
}
int main()
{
    std::cout<<a<<std::endl;
}
//這段程式碼是編不過去的,原因是:
//a變數並沒有指定是哪個名稱空間的變數。所以編譯器找不到這個變數。

再來看下面這個例子:

namespace name1
{
    int a=10;
}
namespace name2
{
    int a=20;
}
int main()
{
    int a=30;
    std::cout<<a<<std::endl;
    std::cout
<<name1::a<<std::endl; std::cout<<name2::a<<std::endl; } //結果: //30 //10 //20

可以看到,我們在main函式中定義了一個區域性變數a,輸出時不指定名稱空間就會輸出該變數a,這是源於c語言中的就近原則,編譯器向上找到了一個最近的區域性變數a,就不會去別的地方找,直接輸出。
第二個輸出10,原因是指定了名稱空間name1,所以編譯器會在該名稱空間內找該變數a,name2同理。

也就是說,名稱空間的意義實際上是為了防止命名衝突的。

那麼我們經常寫c++程式碼時,會寫一句:

using
namespace std;

這是為什麼?
原因是由於:標準c++庫中的所有元件都是在一個被稱為std的名字空間中宣告和定義的。因此,只要使用c++庫中的元件,只要寫一個using namespace std即可。或者使用std::成員的方式來使用。這句話的實際意思是,將std的名稱空間展開到全域性域上,所以在你的程式碼任何地方都可以使用該名稱空間中的元件,但是,尤為重要的一點,一旦你將該名稱空間展開為全域性域之後,變數的命名就不能夠與std中的識別符號重名。
如下面的程式碼:

using namespace std;
int main()
{
    int max=10;
    std::cout<<max(1,2)<<std::endl;
}
//顯然這兩個max的含義不同,第一個max是我自己定義的變數,第二個max是std庫裡的函式名。

輸入輸出

cout是標準輸出流物件,<< 是輸出操作符

cin是標準輸入流物件,>>是輸入操作符

都屬於C++標準庫,所以都在std的名字空間裡面。

格式控制輸出流,不如使用c語言輸出更加直觀

例項:

cout<<"hello world!"<<endl;
cin>>num;

預設引數

全預設引數

int add(int a=0,int b=0)
{
    return a+b;
}

半預設引數:只能預設右邊的值

int add(int a,int b=0)
{
    return a+b;
}

注意:預設只能從右向左預設。

*函式過載**

在同一作用域類,一組函式的函式名相同,引數列表不同

“不同” 可以是:引數個數不同/引數型別不同/返回值可同可不同

例項:以下函式均構成函式過載。

int Add(int a)
{
    return a+10;
}
int Add(int a,int b)
{
    return a+b;
}
int Add(char ch1,char ch2)
{
    return ch1+ch2;
}
int Add(int a,char ch2)
{
    return a+ch2;
}
int Add(char ch1,int b)
{
    return ch1+b;
}

​c++是如何支援過載的?

這是由於c++函式名稱修飾規則。我在Linux下使用objdump工具可以檢視到函式名稱修飾的區別。
這裡寫圖片描述
可以看到c++在函式名稱修飾上會在該名稱前加上字首與字尾,但是,字尾很明顯加入了該函式每個引數型別的首字母。