C++?using全解析
一、using的三種用途
C++中的 using 關(guān)鍵字有三種主要用途:
| 用途 | 作用 | 示例 |
|---|---|---|
| 命名空間引入 | 引入命名空間或其中的成員 | using namespace std; |
| 類型別名 | 給類型起別名 | using int_ptr = int*; |
| 模板別名 | 給模板類型起別名 | template<class T> using Vec = vector<T>; |
二、using 命名空間引入
1. using 聲明(引入單個(gè)成員)
引入命名空間中的單個(gè)成員,之后可以直接使用該成員,不用再加命名空間前綴。
#include <iostream>
int main() {
// 沒用 using 之前,必須寫 std::
std::cout << "Hello" << std::endl;
// 用 using 聲明后,可以直接寫 cout 和 endl
using std::cout;
using std::endl;
cout << "Hello" << endl; // 不需要 std::
// 其他沒引入的成員,仍然需要 std::
int a;
std::cin >> a; // cin 沒引入,還是要寫 std::
return 0;
}說明:using std::cout; 的意思是“把 std 命名空間里的 cout 引入當(dāng)前作用域,以后直接用 cout 就行”。只引入這一個(gè),其他成員不受影響。
2. using 指令(引入整個(gè)命名空間)
引入整個(gè)命名空間,之后所有成員都可以直接使用。
#include <iostream>
using namespace std; // 引入整個(gè) std 命名空間
int main() {
cout << "Hello" << endl; // 直接使用
int a;
cin >> a;
return 0;
}3. 使用建議
| 場(chǎng)景 | 建議 |
|---|---|
| 頭文件 | ? 不要用 using namespace,用完全限定名(如 std::cout) |
| 源文件 | ? 可以用 using namespace,但優(yōu)先用 using 聲明 |
| 局部作用域 | ? 可以用 using namespace,不影響其他地方 |
4. 注意事項(xiàng):避免二義性
namespace A {
void func() { cout << "A" << endl; }
}
namespace B {
void func() { cout << "B" << endl; }
}
using namespace A;
using namespace B;
int main() {
func(); // ? 錯(cuò)誤:不知道調(diào)用 A::func 還是 B::func
}解決方法:
方法1:不用 using,直接用完整名字
A::func(); // 明確調(diào)用 A 的 func B::func(); // 明確調(diào)用 B 的 func
說明:最安全的方式,不會(huì)有任何歧義,推薦在頭文件或大型項(xiàng)目中使用。
方法2:用 using 聲明,只引入不沖突的成員
using A::func; // 只引入 A 的 func func(); // 調(diào)用 A::func B::func(); // B 的 func 還是寫全名
說明:只引入需要的成員,減少命名空間污染,同時(shí)避免沖突。
方法3:在局部作用域使用
{
using namespace A;
func(); // 在這個(gè)大括號(hào)里,func 指 A::func
}
{
using namespace B;
func(); // 在這個(gè)大括號(hào)里,func 指 B::func
}說明:將 using namespace 限制在局部作用域,不同區(qū)域可以分別使用不同的命名空間,互不影響。
三、using 類型別名
C++11 引入了 using 作為類型別名的新語法,比傳統(tǒng)的 typedef 更直觀。
1. typedef 的用法
typedef unsigned int u_int; // 無符號(hào)整型 typedef char* pChar; // 字符指針 typedef int Array[10]; // 數(shù)組 typedef void (*pFun)(int, int); // 函數(shù)指針
2. using 類型別名
using u_int = unsigned int; // 無符號(hào)整型 using pChar = char*; // 字符指針 using Array = int[10]; // 數(shù)組 using pFun = void(*)(int, int); // 函數(shù)指針
3. 對(duì)比
| 類型 | typedef | using |
|---|---|---|
| 基本類型 | typedef unsigned int u_int; | using u_int = unsigned int; |
| 指針 | typedef char* pChar; | using pChar = char*; |
| 數(shù)組 | typedef int Array[10]; | using Array = int[10]; |
| 函數(shù)指針 | typedef void (*pFun)(int, int); | using pFun = void(*)(int, int); |
using 的優(yōu)勢(shì):語法更直觀,尤其是函數(shù)指針,using pFun = void(*)(int, int); 比 typedef 更容易理解。
4. 更多示例
using value_type = int; using pointer = int*; using const_pointer = const int*; using reference = int&; using const_reference = const int&;
四、using 模板別名(最大優(yōu)勢(shì))
using 最大的優(yōu)勢(shì)是支持模板別名,而 typedef 不能。
1. 定義模板別名
template<class T, size_t N> using Array = T[N];
說明:Array 是一個(gè)模板別名,T 是元素類型,N 是數(shù)組大小。使用時(shí)只需指定這兩個(gè)參數(shù)。
2. 使用示例
int main() {
Array<int, 5> ar; // int ar[5]
Array<int, 5> br; // int br[5]
Array<double, 5> dr; // double dr[5]
Array<int*, 10> par; // int* par[10]
return 0;
}說明:一次定義,多次使用。不同大小、不同類型的數(shù)組都可以用同一個(gè)模板別名。
3. 為什么 typedef 做不到?
// typedef 做不到!必須為每個(gè)類型單獨(dú)寫 typedef int Array_int_5[5]; typedef double Array_double_5[5]; // 無法模板化
原因:typedef 只能給具體的、已經(jīng)確定的類型起別名。如果需要多種類型或大小的數(shù)組,只能重復(fù)寫,無法模板化。
4. 實(shí)際應(yīng)用場(chǎng)景
// 簡(jiǎn)化 STL 容器寫法
template<class T>
using Vec = std::vector<T>;
int main() {
Vec<int> v; // 等價(jià)于 std::vector<int>
Vec<double> d; // 等價(jià)于 std::vector<double>
Vec<string> s; // 等價(jià)于 std::vector<string>
return 0;
}說明:每次寫 std::vector<int> 太長了,用 Vec<int> 代替,代碼更短。而且 Vec 是模板,可以生成任意類型的 vector。
五、完整示例
下面的代碼演示了 using 的兩種主要用法:類型別名和模板別名。
#include <iostream>
#include <vector>
using namespace std;
// 1. 類型別名:簡(jiǎn)化復(fù)雜類型
using UInt = unsigned int;
using PFunc = void(*)(int); // 函數(shù)指針類型
// 2. 模板別名:簡(jiǎn)化嵌套容器
template<class T>
using Vec2D = vector<vector<T>>; // 二維數(shù)組
void printInt(int x) {
cout << x << endl;
}
int main() {
// 類型別名使用
UInt a = 10; // unsigned int
PFunc f = printInt; // 函數(shù)指針
f(a);
// 不用模板別名:寫法冗長
vector<vector<int>> m1 = {{1, 2}, {3, 4}};
// 用模板別名:寫法簡(jiǎn)潔
Vec2D<int> m2 = {{1, 2}, {3, 4}}; // 等價(jià)于 vector<vector<int>>
for (auto& row : m2) {
for (auto x : row) {
cout << x << " ";
}
cout << endl;
}
return 0;
}示例說明:
- 類型別名:
UInt比unsigned int短,PFunc讓函數(shù)指針更易讀 - 模板別名:
Vec2D<int>比vector<vector<int>>短很多,嵌套層次越深優(yōu)勢(shì)越明顯
六、總結(jié)
| 用法 | 語法 | 作用 |
|---|---|---|
| 命名空間引入 | using namespace std; | 引入整個(gè)命名空間 |
| using 聲明 | using std::cout; | 引入單個(gè)成員 |
| 類型別名 | using u_int = unsigned int; | 給類型起別名 |
| 模板別名 | template<class T> using Vec = vector<T>; | 給模板起別名 |
注意:
- “命名空間引入”和“using 聲明”是命名空間相關(guān)的用法
- “類型別名”和“模板別名”是類型別名相關(guān)的用法
- 它們雖然都叫
using,但功能完全不同
到此這篇關(guān)于C++ using全解析的文章就介紹到這了,更多相關(guān)C++ using內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言示例講解動(dòng)態(tài)/文件/靜態(tài)功能版本的通訊錄實(shí)現(xiàn)
通訊錄是一個(gè)可以記錄親人、好友信息的工具,這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)通訊錄管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
C++基于UDP協(xié)議的群聊服務(wù)器開發(fā)實(shí)現(xiàn)
本文主要介紹了C/C++基于UDP協(xié)議的群聊服務(wù)器開發(fā),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
C語言?超詳細(xì)順序表的模擬實(shí)現(xiàn)實(shí)例建議收藏
程序中經(jīng)常需要將一組數(shù)據(jù)元素作為整體管理和使用,需要?jiǎng)?chuàng)建這種元素組,用變量記錄它們,傳進(jìn)傳出函數(shù)等。一組數(shù)據(jù)中包含的元素個(gè)數(shù)可能發(fā)生變化,順序表則是將元素順序地存放在一塊連續(xù)的存儲(chǔ)區(qū)里,元素間的順序關(guān)系由它們的存儲(chǔ)順序自然表示2022-03-03
C語言 strcpy和memcpy區(qū)別詳細(xì)介紹
這篇文章主要介紹了C語言 strcpy和memcpy區(qū)別詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-01-01

