1、概述

我们用到的库函数基本上都属于命名空间std的,在程序使用的过程中要显示的将这一点标示出来,如std::cout。这个方法比较烦琐,而我们都知道使用using声明则更方便更安全。

这个我们程序员肯定都知道了,今天突发奇想就想对using整理一下。

2、命令空间的using声明

我们在书写模块功能时,为了防止命名冲突会对模块取命名空间,这样子在使用时就需要指定是哪个命名空间,使用using声明,则后面使用就无须前缀了。例如:

using std::cin;  //using声明,当我们使用cin时,从命名空间std中获取它
int main()
{int i;cin >> i;  //正确:cin和std::cin含义相同cout << i;    //错误:没有对应的using声明,必须使用完整的名字return 0;
}

需要注意的是每个名字需要独立的using声明。例如:

using std::cin;  //必须每一个都有独立的using声明
using std::cout;  using std::endl;  //写在同一行也需要独立声明

位于头文件的代码一般来说不应该使用using声明。因为头文件的内容会拷贝到所有引用它的文件中去,如果头文件里有某个using声明,那么每个使用了该头文件的文件就都会有这个声明,有可能产生名字冲突。

3、在子类中引用基类成员

在子类中对基类成员进行声明,可恢复基类的防控级别。有三点规则:

  1. 在基类中的private成员,不能在派生类中任何地方用using声明。
  2. 在基类中的protected成员,可以在派生类中任何地方用using声明。当在public下声明时,在类定义体外部,可以用派生类对象访问该成员,但不能用基类对象访问该成员;当在protected下声明时,该成员可以被继续派生下去;当在private下声明时,对派生类定义体外部来说,该成员是派生类的私有成员。
  3. 在基类中的public成员,可以在派生类中任何地方用using声明。具体声明后的效果同基类中的protected成员。
    例如:
class Base
{protected:void test1() { cout << "test1" << endl; }void test1(int a) {cout << "test2" << endl; }int value = 55;
};class Derived : Base  //使用默认继承
{public://using Base::test1; //using只是声明,不参与形参的指定//using Base::value;void test2() { cout << "value is " << value << endl; }
};

我们知道class的默认继承是private,这样子类中是无法访问基类成员的,即test2会编译出错。但是如果我们把上面注释的声明给放开,则没有问题。

注意:using::test1只是声明,不需要形参指定,所以test1的两个重载版本在子类中都可使用。
但是在往下派生,则只能使用无参函数,具体什么原因就不知道了…

4、使用using起别名

相当于传统的typedef起别名。

typedef  std::vector<int> intvec;
using   intvec  = std::vector<int>;  //这两个写法是等价的

这个还不是很明显的优势,在来看一个列子:

typedef void (*FP) (int, const std::string&);

若不是特别熟悉函数指针与typedef,第一眼还是很难指出FP其实是一个别名,代表着的是一个函数指针,而指向的这个函数返回类型是void,接受参数是int, const std::string&。

using FP = void (*) (int, const std::string&);

这样就很明显了,一看FP就是一个别名。using的写法把别名的名字强制分离到了左边,而把别名指向的放在了右边,比较清晰,可读性比较好。比如:

typedef std::string (Foo::* fooMemFnPtr) (const std::string&);
using fooMemFnPtr = std::string (Foo::*) (const std::string&);

来看一下模板别名。

template <typename T>
using Vec = MyVector<T, MyAlloc<T>>;// usage
Vec<int> vec;

若使用typedef

template <typename T>
typedef MyVector<T, MyAlloc<T>> Vec;// usage
Vec<int> vec;

当进行编译的时候,编译器会给出error: a typedef cannot be a template的错误信息。

那么,如果我们想要用typedef做到这一点,需要进行包装一层,如:

template <typename T>
struct Vec
{typedef MyVector<T, MyAlloc<T>> type;
};// usage
Vec<int>::type vec;

正如你所看到的,这样是非常不漂亮的。而更糟糕的是,如果你想要把这样的类型用在模板类或者进行参数传递的时候,你需要使用typename强制指定这样的成员为类型,而不是说这样的::type是一个静态成员亦或者其它情况可以满足这样的语法,如:

template <typename T>
class Widget
{typename Vec<T>::type vec;
};

然而,如果是使用using语法的模板别名,你则完全避免了因为::type引起的问题,也就完全不需要typename来指定了。

template <typename T>
class Widget
{Vec<T> vec;
};

一切都会非常的自然,所以于此,模板起别名时推荐using,而非typedef。

感谢大家,我是假装很努力的YoungYangD(小羊)。

参考资料:
https://zhuanlan.zhihu.com/p/21264013
https://blog.csdn.net/shift_wwx/article/details/78742459

C++using用法相关推荐

  1. c语言中external,static关键字用法

    static用法: 在C中,static主要定义全局静态变量.定义局部静态变量.定义静态函数. 1.定义全局静态变量:在全局变量前面加上关键字static,该全局变量变成了全局静态变量.全局静态变量有 ...

  2. Pandas_transform的用法

    先来看一个实例问题. 如下销售数据中展现了三笔订单,每笔订单买了多种商品,求每种商品销售额占该笔订单总金额的比例.例如第一条数据的最终结果为:235.83 / (235.83+232.32+107.9 ...

  3. Python中yield和yield from的用法

    yield 后面接的是 future 对象 调用方 委托生成器 yield from 直接给出循环后的结果 yield from 委托者和子生成器直接通信 yield from 直接处理stopIte ...

  4. pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法

    squeeze的用法主要就是对数据的维度进行压缩或者解压. 先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的 ...

  5. python yield 和 yield from用法总结

    #例1. 简单输出斐波那契數列前 N 个数 #缺点:该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列 #要提高 fab 函数的可复用性,最好不要直接打印出数列,而 ...

  6. tf.nn.embedding_lookup()的用法

    函数: tf.nn.embedding_lookup( params, ids, partition_strategy='mod', name=None, validate_indices=True, ...

  7. OpenMP用法大全

    OpenMP基本概念 OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的 ...

  8. Dorado用法与示例

    Dorado用法与示例 dorado用后总结 一.dorado概念 dorado的产品全名是"dorado展现中间件".从产品形态上dorado由两部分组成,第一部分是一个具有AJ ...

  9. TensorFlow用法

    TensorFlow用法 什么是TensorFlow TensorFlow是一个开源软件库,用于使用数据流图进行数值计算.图中的节点表示数学运算,而图的边缘表示流动的多维数据数组(张量).这种灵活的体 ...

  10. TensorFlow Keras API用法

    TensorFlow Keras API用法 Keras 是与 TensorFlow 一起使用的更高级别的作为后端的 API.添加层就像添加一行代码一样简单.在模型架构之后,使用一行代码,可以编译和拟 ...

最新文章

  1. STM32固件库的安装与介绍
  2. 六、CPU优化(4)NUMA架构
  3. Flash与组件:国外收费组件网站
  4. 【Python】Python常用的Series 和 Dataframe处理方法
  5. 【Python基础】50个令人大开眼界的 Matplotlib 可视化项目
  6. 安装Xcode在Mac OS X10.7.3上
  7. 【BZOJ2038】【2009国家集训队】小Z的袜子(hose) 分块+莫队
  8. echarts饼图自动显示数据
  9. 计算机修改人类记忆曲线,艾宾浩斯遗忘曲线和费曼技巧
  10. HDU - 1873
  11. 请简述python数据分析流程_简单案例讲解Python数据分析的基本步骤
  12. 将网页添加至收藏夹代码
  13. 金三银四求职季,前端面试题小梳理(HTML、CSS、JS)
  14. LabVIEW Arduino电子称重系统(项目篇—1)
  15. vue3[Vue warn]: Failed to resolve component: XXX If this is a native custom element, make sure to ex
  16. android手机如何到导出电话号码,手机通讯录怎么导入到新手机?三种方法,快速迁移!...
  17. 《30天吃掉那只 TensorFlow2.0》 2-2 三种计算图
  18. 园林景观cad_极轴对象跟踪对象捕捉和dyn - AutoCAD 园林景观全面教程 初级篇 - 园林景观设计学院...
  19. c语言程序设计神奇算式,神奇算式
  20. python请输入用户名编程_Python基础练习之用户登录实现代码分享

热门文章

  1. python如何安装第三方包
  2. 2018年最新bluehost主机(中文站)购买教程,送30%优惠码!
  3. About TexturePacker
  4. opencv检测图片失焦 python_如何在Python中使用OpenCV执行模糊检测
  5. windows下创建进程,CreateProcess()详解及用法
  6. Windows命令行查看文件的MD5
  7. 各位同意转载博文的善意,是否被恶意利用?文章被转载了,该不该收钱?
  8. stm32 ADXL345传感器
  9. parameterType、parameterMap与resultMap
  10. Android QQ 登录接入详细介绍