C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ using

C++ using全解析

作者:CoderMeijun

文章详细介绍了C++中的`using`关键字的三种主要用途,文章通过示例详细阐述了`using`的不同用法及其优势,结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

一、using的三种用途

C++中的 using 关键字有三种主要用途:

用途作用示例
命名空间引入引入命名空间或其中的成员using namespace std;
类型别名给类型起别名using int_ptr = int*;
模板别名给模板类型起别名template<class T> using Vec = vector<T>;

二、using 命名空间引入

1. using 声明(引入单个成员)

引入命名空间中的单个成员,之后可以直接使用该成员,不用再加命名空间前缀。

#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 引入当前作用域,以后直接用 cout 就行”。只引入这一个,其他成员不受影响。

2. using 指令(引入整个命名空间)

引入整个命名空间,之后所有成员都可以直接使用。

#include <iostream>
using namespace std;  // 引入整个 std 命名空间

int main() {
    cout << "Hello" << endl;  // 直接使用
    int a;
    cin >> a;
    return 0;
}

3. 使用建议

场景建议
头文件❌ 不要用 using namespace,用完全限定名(如 std::cout
源文件✅ 可以用 using namespace,但优先用 using 声明
局部作用域✅ 可以用 using namespace,不影响其他地方

4. 注意事项:避免二义性

namespace A {
    void func() { cout << "A" << endl; }
}

namespace B {
    void func() { cout << "B" << endl; }
}

using namespace A;
using namespace B;

int main() {
    func();  // ❌ 错误:不知道调用 A::func 还是 B::func
}

解决方法

方法1:不用 using,直接用完整名字

A::func();  // 明确调用 A 的 func
B::func();  // 明确调用 B 的 func

说明:最安全的方式,不会有任何歧义,推荐在头文件或大型项目中使用。

方法2:用 using 声明,只引入不冲突的成员

using A::func;  // 只引入 A 的 func
func();         // 调用 A::func
B::func();      // B 的 func 还是写全名

说明:只引入需要的成员,减少命名空间污染,同时避免冲突。

方法3:在局部作用域使用

{
    using namespace A;
    func();  // 在这个大括号里,func 指 A::func
}
{
    using namespace B;
    func();  // 在这个大括号里,func 指 B::func
}

说明:将 using namespace 限制在局部作用域,不同区域可以分别使用不同的命名空间,互不影响。

三、using 类型别名

C++11 引入了 using 作为类型别名的新语法,比传统的 typedef 更直观。

1. typedef 的用法

typedef unsigned int u_int;      // 无符号整型
typedef char* pChar;              // 字符指针
typedef int Array[10];            // 数组
typedef void (*pFun)(int, int);   // 函数指针

2. using 类型别名

using u_int = unsigned int;       // 无符号整型
using pChar = char*;              // 字符指针
using Array = int[10];            // 数组
using pFun = void(*)(int, int);   // 函数指针

3. 对比

类型typedefusing
基本类型typedef unsigned int u_int;using u_int = unsigned int;
指针typedef char* pChar;using pChar = char*;
数组typedef int Array[10];using Array = int[10];
函数指针typedef void (*pFun)(int, int);using pFun = void(*)(int, int);

using 的优势:语法更直观,尤其是函数指针,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 模板别名(最大优势)

using 最大的优势是支持模板别名,而 typedef 不能。

1. 定义模板别名

template<class T, size_t N>
using Array = T[N];

说明Array 是一个模板别名,T 是元素类型,N 是数组大小。使用时只需指定这两个参数。

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;
}

说明:一次定义,多次使用。不同大小、不同类型的数组都可以用同一个模板别名。

3. 为什么 typedef 做不到?

// typedef 做不到!必须为每个类型单独写
typedef int Array_int_5[5];
typedef double Array_double_5[5];
// 无法模板化

原因typedef 只能给具体的、已经确定的类型起别名。如果需要多种类型或大小的数组,只能重复写,无法模板化。

4. 实际应用场景

// 简化 STL 容器写法
template<class T>
using Vec = std::vector<T>;

int main() {
    Vec<int> v;        // 等价于 std::vector<int>
    Vec<double> d;     // 等价于 std::vector<double>
    Vec<string> s;     // 等价于 std::vector<string>
    return 0;
}

说明:每次写 std::vector<int> 太长了,用 Vec<int> 代替,代码更短。而且 Vec 是模板,可以生成任意类型的 vector。

五、完整示例

下面的代码演示了 using 的两种主要用法:类型别名和模板别名。

#include <iostream>
#include <vector>
using namespace std;

// 1. 类型别名:简化复杂类型
using UInt = unsigned int;
using PFunc = void(*)(int);  // 函数指针类型

// 2. 模板别名:简化嵌套容器
template<class T>
using Vec2D = vector<vector<T>>;  // 二维数组

void printInt(int x) {
    cout << x << endl;
}

int main() {
    // 类型别名使用
    UInt a = 10;           // unsigned int
    PFunc f = printInt;    // 函数指针
    f(a);
    
    // 不用模板别名:写法冗长
    vector<vector<int>> m1 = {{1, 2}, {3, 4}};
    
    // 用模板别名:写法简洁
    Vec2D<int> m2 = {{1, 2}, {3, 4}};  // 等价于 vector<vector<int>>
    
    for (auto& row : m2) {
        for (auto x : row) {
            cout << x << " ";
        }
        cout << endl;
    }
    
    return 0;
}

示例说明

六、总结

用法语法作用
命名空间引入using namespace std;引入整个命名空间
using 声明using std::cout;引入单个成员
类型别名using u_int = unsigned int;给类型起别名
模板别名template<class T> using Vec = vector<T>;给模板起别名

注意

到此这篇关于C++ using全解析的文章就介绍到这了,更多相关C++ using内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文