C++中using关键字全面讲解

C++基础之关键字——using使用详解 目前为止C++中的using关键字主要有三中使用场景,从C++ 11开始新增了第三种。下面我们分别介绍一下。 指示使用某命名空间,对命名空间成员进行声明也就是说指明用哪个命名空间的成员 Using-directives:指示使用某命名空间,这也是最常见的使用方法 语法: attr(optional) using namespace nested-name-specifier(optional) namespace-name; attr: 应用到using的任意数量的属性, nested-name-spe 阅读详情

C++中using关键字全面讲解

1. using关键字的主要用途

using在C++中有三个主要用途:

1.1 类型别名(Type Aliases) - C++11引入

这是typedef的现代替代品,语法更清晰易懂。

// 传统typedef
typedef std::vector<std::map<std::string, int>> ComplexType;

// 现代using(推荐)
using ComplexType = std::vector<std::map<std::string, int>>;

// 模板别名(using独有功能)
template<typename T>
using MyAllocVector = std::vector<T, MyAllocator<T>>;

MyAllocVector<int> v; // 使用自定义分配器的vector

为什么推荐using而不是typedef:

  • 语法更自然,类似变量声明
  • 可读性更强,特别是对于函数指针类型
  • 支持模板别名(typedef不支持)

1.2 命名空间使用(Namespace Usage)

// 整个命名空间引入(谨慎使用)
using namespace std;

// 选择性引入特定成员(推荐)
using std::cout;
using std::endl;
using std::vector;

// 在函数内部局部引入
void func() {
    using namespace std;
    cout << "局部使用" << endl;
}

1.3 继承构造函数(Inheriting Constructors) - C++11引入

class Base {
public:
    Base(int x) { /* ... */ }
    Base(int x, int y) { /* ... */ }
};

class Derived : public Base {
public:
    using Base::Base; // 继承Base的所有构造函数
    // 编译器会为Derived生成:
    // Derived(int x) : Base(x) {}
    // Derived(int x, int y) : Base(x, y) {}
};

2. 详细用法和示例

2.1 类型别名的高级用法

#include <iostream>
#include <vector>
#include <map>

// 基础类型别名
using String = std::string;
using IntVector = std::vector<int>;

// 函数指针别名(比typedef清晰很多)
using Comparator = bool(*)(int, int);

bool ascending(int a, int b) { return a < b; }
bool descending(int a, int b) { return a > b; }

// 模板别名
template<typename T>
using StringMap = std::map<std::string, T>;

template<typename T, int Size>
using FixedArray = std::array<T, Size>;

int main() {
    Comparator comp = ascending;
    std::cout << comp(1, 2) << std::endl; // 1 (true)
    
    StringMap<int> ageMap;
    ageMap["Alice"] = 25;
    
    FixedArray<double, 10> arr;
    return 0;
}

2.2 命名空间的最佳实践

#include <vector>
#include <algorithm>

// 不好的做法:全局引入整个std命名空间
// using namespace std;

// 好的做法:选择性引入或在局部引入
using std::vector;
using std::sort;

namespace MyLibrary {
    void importantFunction() {
        // 在函数内部局部引入
        using namespace std;
        vector<int> v = {1, 2, 3};
        sort(v.begin(), v.end());
    }
    
    // 或者使用全限定名
    void anotherFunction() {
        std::vector<int> v;
        std::sort(v.begin(), v.end());
    }
}

2.3 继承构造函数的细节

#include <iostream>

class Base {
private:
    int value;
public:
    Base() : value(0) { std::cout << "Base()" << std::endl; }
    Base(int v) : value(v) { std::cout << "Base(" << v << ")" << std::endl; }
    
    void print() { std::cout << "Value: " << value << std::endl; }
};

class Derived : public Base {
public:
    using Base::Base; // 继承所有构造函数
    
    // 可以添加自己的成员函数
    void derivedFunction() {
        std::cout << "Derived function" << std::endl;
    }
};

int main() {
    Derived d1;        // 调用Base()
    Derived d2(42);    // 调用Base(42)
    d2.print();        // Value: 42
    d2.derivedFunction();
    return 0;
}

3. 底层原理和特性

3.1 类型别名的底层机制

using创建的类型别名在编译期完全等价于原始类型,不会产生运行时开销:

using MyInt = int;
MyInt x = 10;

// 编译后,MyInt和int完全一样
// 类型检查、函数重载决议等都按原始类型处理

3.2 模板别名的强大之处

这是using相比typedef的最大优势:

// typedef无法做到的模板别名
template<typename T>
struct MyContainer {
    typedef std::vector<T> type; // 需要嵌套在struct中
};

// 使用起来很繁琐
MyContainer<int>::type vec1;

// using直接实现模板别名
template<typename T>
using MyContainer = std::vector<T>;

MyContainer<int> vec2; // 简洁明了

3.3 SFINAE和模板元编程中的应用

#include <type_traits>

// 使用using进行类型traits检查
template<typename T>
using IsIntegral = typename std::is_integral<T>::type;

template<typename T>
using EnableIfIntegral = typename std::enable_if<std::is_integral<T>::value>::type;

template<typename T, typename = EnableIfIntegral<T>>
void process(T value) {
    // 只接受整数类型
}

4. 使用场景和最佳实践

4.1 什么时候使用using?

使用类型别名的情况:

  • 简化复杂类型声明时
  • 创建平台无关的类型时
  • 模板编程中需要类型转换时
  • 提高代码可读性时

使用命名空间的情况:

  • 在源文件中(非头文件)可以适当使用
  • 在函数内部局部使用
  • 选择性引入常用名称

4.2 什么时候避免using?

头文件中避免:

// myheader.h - 不好的做法
using namespace std; // 污染全局命名空间

// 好的做法:在头文件中使用全限定名
namespace MyLibrary {
    void func(std::vector<int>& v) {
        std::sort(v.begin(), v.end());
    }
}

5. 综合示例:现代C++代码风格

#include <iostream>
#include <vector>
#include <memory>
#include <type_traits>

// 使用using定义常用类型
template<typename T>
using UniquePtr = std::unique_ptr<T>;

template<typename T>
using SharedPtr = std::shared_ptr<T>;

// 函数类型别名
using Handler = void(*)(int, const std::string&);

// 复杂的容器类型别名
template<typename Key, typename Value>
using StringMap = std::map<std::string, Value>;

class NetworkService {
private:
    using Callback = std::function<void(bool)>;
    
public:
    void connect(const std::string& address, Callback callback) {
        // 实现连接逻辑
    }
};

int main() {
    // 使用类型别名让代码更清晰
    UniquePtr<std::vector<int>> data = std::make_unique<std::vector<int>>();
    StringMap<int> config;
    
    NetworkService service;
    service.connect("localhost", [](bool success) {
        std::cout << (success ? "Connected" : "Failed") << std::endl;
    });
    
    return 0;
}

6. 总结

using关键字是现代C++编程中的重要工具:

  1. 类型别名:比typedef更清晰,支持模板别名
  2. 命名空间管理:合理使用可以提高代码可读性
  3. 继承构造函数:简化派生类的构造函数编写

关键要点:

  • 在头文件中谨慎使用using namespace
  • 优先使用using而不是typedef
  • 利用模板别名简化复杂类型
  • 理解底层原理:编译期替换,无运行时开销

像是using等很多关键字都有着广泛而大量的用法,必须在实践中学习,并且尝试自己去使用,遇到问题再去查阅资料,这才是正确的学习方法!

C++——using 关键字 如果代码是这样的话,struct X {X x;Y y;x.f(1);y.f(1);y.f(1.0);return 0;执行结果如下:如果代码是这样的话。Y y;x.f(1);y.f(1);y.f(1.0);return 0;执行结果如下:为什么会这样呢?这是因为如果派生类中定义了与基类中同名的成员函数,则派生类中的同名函数会覆盖基类的函数。这被称为函数重写或函数覆盖。 阅读详情

相关推荐

c++11新特性篇-using的使用

在 C++11 之前就有,但在 C++11 中引入了一些扩展和新的用法。在 C++中可以通过 typedef 重定义一个类型,语法格式如下: 被重定义的类型并不是一个新的类型,仅仅只是原有的类型取了一个新的名字。再看一个复杂点的例子: 上面两行代码将 定义为 的别名,所以后续使用 就相当于使用 。将 定义为 的别名,而 定义为 的别名,即指向 (也就是 )类型的指针。综合起来就是: using 在使用的时候,关键字using作为别名声明的开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定成

f593256的博客 918

c++中using的用法

1、概述 我们用到的库函数基本上都属于命名空间std的,在程序使用的过程中要显示的将这一点标示出来,如std::cout。这个方法比较烦琐,而我们都知道使用using声明则更方便更安全。 这个我们程序员肯定都知道了,今天突发奇想就想对using整理一下。 2、命令空间的using声明 我们在书写模块功能时,为了防止命名冲突会对模块取命名空间,这样子在使用时就需要指定是哪个命名空间,使用using声...

weixin_39640298的博客 3万+

隐藏与using关键字

前言 C++经常有重载,覆盖(重写),隐藏(重定义)。这三者区别看我这篇博客:重载、重写(覆盖)、隐藏(重定义)。 这里讲隐藏:隐藏是发生在基类和派生类之间的。如果在派生类中定义了一个与基类同名的函数,不管这个函数的参数列表是不是与基类中的函数相同,则这个同名的函数就会把基类中的所有这个同名的函数的所有重载版本都隐藏了,这时并不是在派生类中重载基类的同名成员函数,而是隐藏。 1 隐藏基...

路漫漫其修远兮 425

C++ 中using 的使用

若不是特别熟悉函数指针与typedef的童鞋,我相信第一眼还是很难指出FP其实是一个别名,代表着的是一个函数指针,而指向的这个函数返回类型是void,接受参数是int, const std::string&。我想,即使第一次读到这样代码,并且不知道 C++11 using 用法的童鞋也能很容易知道 FP 是一个别名,using 的写法把别名的名字强制分离到了左边,而把别名指向的放在了右边,比较清晰。今天在看vector.h的时候,碰到一个using的奇怪用法,才疏学浅之前没有碰到过,整理一下。

私房菜 10万+

数据湖是什么?有什么优势?与数仓区别?未来的发展?

数据湖是什么?有什么优势?与数仓区别?未来的发展?一、什么是数据湖二、数据湖的发展三、数据湖有哪些优势四、数据湖应该具备哪些能力五、数据湖的实现遇到了哪些问题六、数据湖与数据仓库的区别七、为什么要做数据湖?区别在于?八、数据湖挑战九、湖仓一体十、目前有哪些开源数据湖组件 来源:大数据DT 一、什么是数据湖 数据湖是一种不断演进中、可扩展的大数据存储、处理、分析的基础设施;以数据为导向,实现任意来源、任意速度、任意规模、任意类型数据的全量获取、全量存储、多模式处理与全生命周期管理;并通过与各类外部异构数据

一个写湿的程序猿 9136

PostgreSQL中idle in transaction状态的5个隐藏危害及实战解决方案

本文深入剖析了PostgreSQL中`idle in transaction`连接状态的五大隐藏危害,包括内存与锁泄漏、VACUUM受阻导致表膨胀、事务ID加速消耗、连接池资源耗尽以及增加故障排查复杂度。文章提供了基于`pg_stat_activity`视图的监控方法、识别高危事务的SQL脚本,并给出了从数据库参数调优(如设置`idle_in_transaction_session_timeout`)到应用层编码规范与连接池配置的完整实战解决方案。

zzz56的博客 232

【C++】using关键字

命名空间,定义类型别名,继承基类成员、类型萃取、与decltype配合推导类型

志之所趋,无远弗届,穷山距海,不能限也 781

Rider高效调试UE引擎:无需编译源码的符号配置指南

本文提供了一份详尽的Rider高效调试UE引擎指南,核心在于无需编译源码即可配置调试符号。通过Epic启动器下载官方PDB文件,并在Rider中正确配置外部符号服务器路径,开发者能在10分钟内实现对引擎内部代码(如AActor::Tick)的源码级断点调试、变量查看和调用堆栈分析,极大提升问题排查效率。

weixin_29011239的博客 336

using的三种用法

1、命名空间的使用 一般为了代码的冲突,都会 用命名空间。例如,对于Android代码会使用Android作为命名空间。 namespace android; 在code中使用的时候可以用android::加具体的类方法。 也可以直接使用 using namespace android; 这样可以直接使用 命名空间 android 下的方法 类型 成员 2、在子类中引用基类的成员 class T5Base { public: T5Base() :value(55) {} ...

qq_27898413的博客 1617

角谱迭代与傅里叶变换迭代算法(GS)的原理及其实例演示分析

角谱迭代与傅里叶变换迭代算法(GS)的原理及其实例演示分析 目前,迭代法和强度传输方程(TIE)法是两类典型的非干涉相位检索技术(Phase Retrieval,被称为相位恢复、相位检索、相位反演法、相位复原等)。迭代法中的经典算法是Gerchberg-Saxton(GS),随后,出现了包括错误减少算法(ER)、混合输入输出法(HIO)、梯度搜索算法、角谱迭代算法等改进算法。...

简单光学 2万+

AI智能体协作:构建更精准的公司破产预测模型

公司破产预测对于金融机构、投资者和监管部门等具有至关重要的意义。准确的破产预测可以帮助金融机构提前做好风险防范,避免贷款损失;投资者可以根据预测结果调整投资组合,降低投资风险;监管部门可以及时发现潜在的金融风险,采取相应的监管措施。然而,传统的公司破产预测模型往往存在精度不高的问题,无法满足实际需求。本研究的目的是利用AI智能体协作的方式,构建一个更精准的公司破产预测模型。通过将多个AI智能体的优势进行整合,充分挖掘公司财务数据、市场数据等多源数据中的信息,提高预测的准确性和可靠性。

2501_92132293的博客 1077

C++中using的三种用法

1、导入命名空间 C++命名空间namespace的理解 使用C++在写不同的功能模块时,为了防止命名冲突,建议对模块取命名空间,这样在使用时就需要指定是哪个命名空间。 使用 using 导入命名空间,即使一个命名空间中的所有名字都在该作用域中可见,常见的如下: // 导入整个命名空间到当前作用域 using namespace std; // 只导入某个变量到当前作用域 using std::cout; 在.h头文件中,一般不应该使用using声明。 因为头文件的内容会拷贝...

juruiyuan111的专栏 2699

C#串口通信从入门到精通(7)——整数/浮点数与二进制、八进制、十六进制之间的转换与C#实现

本文详细介绍由博主开发的DataConvert串口通信帮助类的用法,该帮助类涵盖了串口通信领域所有的数据转换方法,帮助大家快速编写串口通信程序!

qq_34059233的博客 2867

C++ using详解

using是C++中功能多样的关键字。本文详解using的三种用法:命名空间引入、类型别名、模板别名,以及与typedef的对比,一篇搞懂C++ using。

yeliyuna000的博客 398

MATLAB点云处理总目录

点云处理研究学习

weixin_44329757的博客 2551

华为数通方向HCIP-DataCom H12-831题库(多选题:121-140)

华为数通HCIP H12-831多选题

didiplus 1286

C++ using 的用法

命名空间 using namespace 命名空间; 类型别名(C++11) using INT = int; 改变从基类继承来的成员的访问级别 class base { public: int func(int); int data_; }; class son : private base { public: using base::func; pro...

LU_ZHAO的博客 718

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++11 使用using定义类型别名

传统的定义类型别名的方法是使用关键字typedef: typedef double NOUBLE; 我们也可以使用#define来定义别名(使用预处理器) #define NOUBLE double 在C++11中使用关键字using来进行别名声明 假设我们现在定义了结构体MyString,那么我们可以使用using为MyString类型设置一个别名: using MS = MyString; 这样我们在定义该结构体类型变量时,就可以使用MS作为类型名了 MS TempString; ...

肥嘟嘟的左卫门 1720

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++ 命名空间,作用域运算符和using关键字

C++ 命名空间,作用域运算符和using关键字 个人理解,极其主观,仅供参考! C++ 作用域运算符 C++的作用域运算符主要起到区别作用,避免产生二义性,在不同的模块可能有相同的标识符名称,需要用::加以区分。 主要用于: 命名空间 全局变量 类(static情况,继承情况) 见文章:C++作用域运算符::的用法 (360doc.com) C++ 命名空间 使用命名空间实际上也是避免不同的空间内的标识符相同导致二义性,可以通过使用作用域运算符确定此标识符处于什么空间,也可以使用using nam

man_skill的博客 543

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【C++入门】使用using重新定义继承的成员访问权限

(1)父类的public成员在private/protected继承后,在派生类中就成了private/protected权限而不是public权限,子类对象就不能再调用父类的public成员;(2)可能在父类中有100个public成员,在子类对象中只需要访问1个成员,其余99个成员都不需要访问,合适的做法是将100个父类的public成员以private/protected权限继承到子类,然后使用using关键字对需要访问的那一个父类public成员进行权限修改;

weixin_42031299的博客 1066

38.C++ typedef与using、string的简单使用(c++11的新特性)

今天进行了新的学习,c++11新特性中关于using和string的使用。在c语言中我们已经进行了typedef的学习,你是否还记得呢?首先就让我们先来回顾一下。

weixin_63779802的博客 995

[cpp][命名空间][namespace][cpp初阶][一][4]详细讲解

> 分而治之 <-在C++ 标准库中已经有一名为rand的函数,它位于[cstdio.h]头文件中.当你在代码中又定义了一名为rand的全局变量时,就产生了命名冲突. 编译器会分不清楚。

2301_80443197的博客 856

c++中的using和constexpr

using和constexpr关键字using关键字constexpr关键字 using关键字 命名空间及其成员的导入 直接导入整个命名空间 //e.g. // using namespace space_NAME using namespace std; //注:不要在同一程序中引入两个及以上的命名空间 导入某一命名空间的单个成员 //e.g. // using namespace space_NAME::space_MEMBER using namespace std::cout;

来,骗!来,偷袭! 2785

cpoint类在哪个头文件中_C++中using的三种用法

1、导入命名空间C++命名空间namespace的理解使用C++在写不同的功能模块时,为了防止命名冲突,建议对模块取命名空间,这样在使用时就需要指定是哪个命名空间。使用 using 导入命名空间,即使一个命名空间中的所有名字都在该作用域中可见,常见的如下:// 导入整个命名空间到当前作用域using namespace std;// 只导入某个变量到当前作用域 using std::cout; 在...

weixin_39649611的博客 998

C++ using关键字:从基础用法到高级模板编程

在C++编程语言中,类型别名和命名空间管理是提升代码可读性与维护性的重要技术。通过using关键字,开发者可以创建直观的类型别名替代传统的typedef,特别是在处理复杂模板类型时展现出明显优势。从编译器实现原理看,using在符号表中建立名称映射关系,这种编译期机制不会引入运行时开销。现代C++标准中,using已发展为支持模板别名、继承体系调整等高级特性的多功能工具,广泛应用于元编程、接口设计等场景。特别是在构建类型萃取器和处理SFINAE时,using与模板的结合使用成为标准库开发的常见模式。

weixin_33585822的博客 246

C/C++ 知识点:typedef 关键字

这样,每当你在代码中使用ullong时,就相当于在使用类型。在C++中,虽然结构体(struct)和类(class)在语义上有所不同,但它们都可以被typedef用来定义别名。然而,自C++11起,推荐使用using关键字为类型定义别名,但对于结构体和联合体的别名定义,typedef仍然被广泛使用。int x, y;} Point;在C++中定义结构体时,如果不使用typedefint x, y;但在C语言中,如果要在不指定struct关键字的情况下使用Point类型,则必须使用。

个人技术博客 816
上一篇: C++匿名函数深度解析:从语法到实践的全方位指南
下一篇: 深入理解C++中的数组指针:类型系统的魔法
泡泡茶壶ᐇ
博客等级 码龄3年 185粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值