C++超詳細(xì)梳理基礎(chǔ)知識(shí)
命名空間的使用
來(lái)源
在了解命名空間的原理和使用之前,我們先要理解,命名空間是為了解決什么問(wèn)題。
C++是在C的基礎(chǔ)上發(fā)展而形成的一種語(yǔ)言,完全兼容C的語(yǔ)法,也加入了許多新的規(guī)則和語(yǔ)法來(lái)解決C的缺陷。
命名空間就是為了解決C語(yǔ)言中的重復(fù)命名的問(wèn)題。
首先我們來(lái)看看這么一個(gè)代碼:
#include<stdio.h>
int main()
{
int scanf = 20;
printf("%d", scanf);
return 0;
}我們都知道scanf在C之中是一個(gè)函數(shù)名,但詭異的是我們?cè)谥骱瘮?shù)中聲明scanf是有效的并且輸出結(jié)果是20.

在這個(gè)程序內(nèi)的scanf就是表示是一個(gè)int型整數(shù),這是根據(jù)就近原則或者說(shuō)是局部?jī)?yōu)先原則確定的。
接下來(lái)我們看看另一個(gè)程序:
#include<stdio.h>
int main()
{
int scanf = 20;
scanf("%d", &scanf);
printf("%d", scanf);
return 0;
}在我們想要scanf作為函數(shù)使用時(shí)出現(xiàn)了問(wèn)題,兩者之間命名沖突。
在C語(yǔ)言中我們被告誡不要讓變量名與函數(shù)名沖突,但是在C++中有沒(méi)有合適的解決方法呢?
命名空間的使用
我們先來(lái)書(shū)寫一個(gè)在C++中最為簡(jiǎn)單的程序:
#include<iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}這里我們就看到了namespace命名空間,但是現(xiàn)在它是用來(lái)干什么的我們還不清楚,首先我們先來(lái)了解一下它。
一個(gè)命名空間就定義了一個(gè)新的作用域,命名空間中的所有內(nèi)容都局限于該命名空間中。
讓我們從代碼方面來(lái)看看命名空間到底是什么:
#include<iostream>
using namespace std;
namespace N1
{
int printf = 30;
int strlen = 20;
}
int main()
{
cout << "hello world" << endl;
cout << N1::printf << endl;
return 0;
}我們聲明了一個(gè)命名空間N1,在內(nèi)部聲明了兩個(gè)int類型的變量,通過(guò)作用域限定符::我們就可以調(diào)用命名空間中的變量。
并且命名空間中也可以嵌套命名空間:
namespace N1
{
int printf = 30;
int strlen = 20;
namespace N2
{
int a = 0;
}
}通過(guò)上面的解釋,我們明白了,命名空間適用于將聲明的名稱之間相互隔離,防止命名沖突。比如說(shuō),我們調(diào)用N1::printf時(shí),::將范圍限定在N1這個(gè)命名空間之中,而不會(huì)與函數(shù)名printf沖突,反之亦然。
那么一開(kāi)始我們看到的那個(gè)程序是什么意思呢?
我們先來(lái)看另一個(gè)版本的程序:
int main()
{
std::cout << "hello world" << std::endl;
//cout << N1::printf << endl;
return 0;
}顯然std也是一個(gè)命名空間,通過(guò)作用域限定符調(diào)用命名空間std內(nèi)的內(nèi)容。
那么一開(kāi)始的
using namespace std;
是用來(lái)干嘛的呢?
using的作用是把命名空間中的內(nèi)容在全局空間中展開(kāi),命名空間中的變量就成為了全局變量,調(diào)用時(shí)就不需要命名空間名加上作用域限定符了。
實(shí)際上命名空間有三種使用方式,各有優(yōu)劣。
不展開(kāi)
也就是
std::cout << "hello world" << std::endl;
的方式,要使用命名空間中的名稱,就要使用::來(lái)限定命名空間,完全避免了沖突,在大工程中使用。缺點(diǎn)就是在日常練習(xí)中書(shū)寫代碼較為繁瑣。
部分展開(kāi)
使用using將命名空間中成員引入,將一些我們常用的符號(hào)在全局中展開(kāi),就可以大大簡(jiǎn)化代碼,是在第一個(gè)方法和第三個(gè)方法之間取一個(gè)折中。
using std::cout;
using std::endl;
int main()
{
cout << "hello world" << endl;
//cout << N1::printf << endl;
return 0;
}全展開(kāi)
使用using namespace 命名空間名稱引入:
using namespace std;
int main()
{
cout << "hello world" << endl;
//cout << N1::printf << endl;
return 0;
}這個(gè)方法是有問(wèn)題的,相當(dāng)于一夜回到解放前。好不容易搞個(gè)命名空間隔離了,結(jié)果一行代碼全給展開(kāi)了,直接在全局空間聲明,完全沒(méi)有防止命名沖突的作用,只在日常練習(xí)中使用。
函數(shù)重載
函數(shù)重載的規(guī)則
自然語(yǔ)言中,一個(gè)詞可以有多重含義,人們可以通過(guò)上下文來(lái)判斷該詞真實(shí)的含義,即該詞被重載了。
比如:以前有一個(gè)笑話,國(guó)有兩個(gè)體育項(xiàng)目大家根本不用看,也不用擔(dān)心。一個(gè)是乒乓球,一個(gè)是男足。前者是“誰(shuí)也贏不了!”,后者是“誰(shuí)也贏不了!”
函數(shù)重載是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個(gè)功能類似的同名函數(shù),這些同名函數(shù)的形參列表(參數(shù) 個(gè)數(shù) 或 類型 或 順序)必須不同,常用來(lái)處理實(shí)現(xiàn)功能類似數(shù)據(jù)類型不同的問(wèn)題。
比如下面的相加函數(shù):
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, 20);
Add(10.0, 20.0);
Add(10L, 20L);
return 0;
}雖然函數(shù)名相同,但是所帶參數(shù)的類型不同,所以在調(diào)用的時(shí)候能夠調(diào)用不同的函數(shù)定義,讓函數(shù)的使用更加靈活。
這里要特別注意的是函數(shù)重載的規(guī)則:同名函數(shù)的形參列表(參數(shù) 個(gè)數(shù) 或 類型 或 順序)必須不同。
short Add(short left, short right)
{
return left+right;
}
int Add(short left, short right)
{
return left+right;
}那么兩個(gè)同名函數(shù),算不算是函數(shù)重載呢,顯然他們的形式參數(shù)的個(gè)數(shù) ,類型以及 順序都是一樣的,只是返回類型不同,不構(gòu)成重載函數(shù)。
C++如何實(shí)現(xiàn)函數(shù)重載
我們都知道C是沒(méi)有函數(shù)重載這個(gè)功能的,那么C++是怎么實(shí)現(xiàn)的呢?
其實(shí)是通過(guò)C++的函數(shù)名修飾來(lái)實(shí)現(xiàn)函數(shù)重載的。
大家這里可能有一些迷糊,這需要我們對(duì)代碼的編譯過(guò)程有一定的了解:

C和C++的區(qū)別在于,在編譯的符號(hào)匯總中,C語(yǔ)言是使用函數(shù)的原名進(jìn)行匯總的,導(dǎo)致了一個(gè)名稱只能對(duì)應(yīng)一個(gè)函數(shù),所以不能進(jìn)行函數(shù)重載。
但是在C++中,符號(hào)匯總起來(lái)的是經(jīng)過(guò)修飾的函數(shù)名,即使原名稱一樣,由于參數(shù) 個(gè)數(shù) 或 類型 或 順序不同,經(jīng)過(guò)修飾后的符號(hào)名也不同,比如說(shuō):
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;
}比如說(shuō)這三個(gè)函數(shù)經(jīng)過(guò)函數(shù)名修飾之后就變成了——Addii、Adddd、Addll。于是我們?cè)诤罄m(xù)的使用中就可以很好地區(qū)分這三個(gè)函數(shù)了,即使在我們看來(lái)這三個(gè)函數(shù)名是一樣的,但是在計(jì)算機(jī)看來(lái)這三個(gè)完全就是三個(gè)不一樣的函數(shù)。
引用
引用可以說(shuō)就是給變量取別名。是怎么實(shí)現(xiàn)的呢?
#include<iostream>
int main()
{
int a = 0;
int b = 0;
int& c = a;
c = 10;
return 0;
}其中 int& c = a; 就是把c作為a的別名,這時(shí)c和a指向的內(nèi)存空間是同一塊。

當(dāng)改變c的值時(shí),a中的值同時(shí)改變。

但是,在使用過(guò)程中也有一些需要注意的事項(xiàng)——
1.引用類型必須和引用實(shí)體是同種類型的


2.引用在定義時(shí)必須初始化
int a; int& b = a;

3.一個(gè)變量可以有多個(gè)引用
int a = 0; int& b = a; int& c = a; int$ d = c;
4.引用一旦引用一個(gè)實(shí)體,再不能引用其他實(shí)體
#include<iostream>
int main()
{
int a = 0;
int b = 0;
int& c = a;
int& c = b;
c = 10;
return 0;
}
到此這篇關(guān)于C++超詳細(xì)梳理基礎(chǔ)知識(shí)的文章就介紹到這了,更多相關(guān)C++基礎(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用代碼和UML圖化解設(shè)計(jì)模式之橋接模式的深入分析
本篇文章是對(duì)橋接模式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C++編寫LINUX守護(hù)進(jìn)程的實(shí)現(xiàn)代碼
這篇文章主要介紹了如何使用C++實(shí)現(xiàn)LINUX守護(hù)進(jìn)程,文中代碼非常詳細(xì),供大家學(xué)習(xí)參考,感興趣的小伙伴可以了解下2020-06-06

