using声明与using指示的区别(在作用域上)
2015-11-13 12:41
309 查看
在《C++ Primer》第五版十八章中详细描述了 using 指示与 Using 声明的区别,个人也想了好久。首先,明确一下 using 声明与指示
using 声明: using std::cout;
using 指示: using namespace std;
由上面的例子可以看出,using 指示与 using 声明不仅仅是包含进来的命名空间的名字数目不同的区别。
从书中的原话上看出,using 声明语句的作用效果是从当前语句开始,在当前作用域中余下部分若提到该成员,则均指的是命名空间中的成员。如:
这句话写的真的很绕,我所花费的时间都是在理解这句话,后来问了一下同学(skillness),才正确的对这句话进行了分句。首先这句话的分句如下:
它具有将命名空间成员提升到包含(命名空间本身和 Using 指示)的最近作用域的能力。这里的最近作用域指的是该命名空间本身所在作用域与Using 指示这句话所在作用域的总作用域。而不是,命名空间和using
指示的最近作用域两个作用域。如:
如果我的理解是正确的,那是不是说如果现在C1中也定义了i成员,f()函数中访问i成员就会出现二义性:首先是C2 中的i 被提升到 C1 中,其次是 C1 中自己定义的 i 成员。事实证明,此时就是会报二义性的错误,说明我的理解是对的。测试代码如下:
在上述测试代码中,将 using 指示换成 using 声明将不会出错,因为此时相当于在当前作用域中引入了 C2::i,将会屏蔽外部嵌套命名空间中的同名成员。
using 声明: using std::cout;
using 指示: using namespace std;
1.初步展示区别
在我们通常的理解下,using 声明引入了一个名字,在声明之后的作用域中,所有用到该名字的地方,都是指的改名字。而using 指示则是将命名空间中的所有名字都引入当前作用域,效果有些类似若干个 using 声明。但事实上,这两个是存在很大的不同的。看以下例子:(1)对using 声明:
namespace N1 { int a = 0; } void f() { using N1::a; //此时下文中所有的 a 都将等效为 N1::a int a = 4; //这句话将会导致编译器报重复定义的错误,因为 a 已经定义为 int a = 0,此时再次定义就重定义了 cout << a << endl; }
(2)对 using 指示
namespace N1 { int a = 0; } void f() { using namespace N1; int a = 4; //此时将不会报错,程序正常运行 cout << a << endl; //输出4,可见N1::a 被屏蔽 }
由上面的例子可以看出,using 指示与 using 声明不仅仅是包含进来的命名空间的名字数目不同的区别。
2.两者在作用域上的区别
(1)using 声明
“从效果上看就好像using声明语句为命名空间的成员在当前作用域中创建了一个别名一样” ——《C++ primer》5th从书中的原话上看出,using 声明语句的作用效果是从当前语句开始,在当前作用域中余下部分若提到该成员,则均指的是命名空间中的成员。如:
int i = 1; namespace N { int i = 2; } void f() { cout << i << endl; //输出1 using N::i; //从该语句开始的当前作用域中,所有 i 指的均是 N::i cout << i << endl; //输出2 }
(2)using 指示
“它具有将命名空间成员提升到包含命名空间本身和using指示的最近作用域的能力”——《C++ primer》5th这句话写的真的很绕,我所花费的时间都是在理解这句话,后来问了一下同学(skillness),才正确的对这句话进行了分句。首先这句话的分句如下:
它具有将命名空间成员提升到包含(命名空间本身和 Using 指示)的最近作用域的能力。这里的最近作用域指的是该命名空间本身所在作用域与Using 指示这句话所在作用域的总作用域。而不是,命名空间和using
指示的最近作用域两个作用域。如:
namespace C1 { namespace C2 //命名空间本身的作用域为 C1 { int i = 2; } namespace C3 { namespace C4 { void f() { using namespace C2; //using 指示的作用域是 C4 cout << i << endl; } } } }则包含命名空间本身的作用域C1与using指示所在作用域C4 的作用域是C1作用域。也就是说,对 using 指示所在有效作用于(f函数体内)而言,i 表现得好像是定义在C1 中的成员。
如果我的理解是正确的,那是不是说如果现在C1中也定义了i成员,f()函数中访问i成员就会出现二义性:首先是C2 中的i 被提升到 C1 中,其次是 C1 中自己定义的 i 成员。事实证明,此时就是会报二义性的错误,说明我的理解是对的。测试代码如下:
namespace C1 { int i = 1; namespace C2 { int i = 2; } namespace C3 { namespace C4 { void f() { cout << i << endl; // 输出 1,C1::i using namespace C2; // 将 C2::i 提升到 C1 空间中 cout << i << endl; // 编译器将会提示:i 不明确 } } } }可见,using 指示会将命名空间成员提升到包含双方所在作用域的大作用域中。而不是指的两个作用域!
在上述测试代码中,将 using 指示换成 using 声明将不会出错,因为此时相当于在当前作用域中引入了 C2::i,将会屏蔽外部嵌套命名空间中的同名成员。
相关文章推荐
- pthread_create 参数传递指针问题
- Python3基础教程-廖雪峰[带标签完整版]
- 富文本兼容性问题归纳(win)
- 身份证验证、字符串删除、扩展字母、空格转化、位运算
- JAVA中包和方法变量访问权限
- 黑马程序员_编程范式
- Android中 Bitmap和Drawable相互转换的方法
- webstorm基础使用总结
- Centos安装与配置JDK
- scala ide + helloworld
- Linux程序设计——用getopt处理命令行参数
- 笔试面试成对出现的一组数,只有一个或两个只出现一次的数字,找到它们。
- iOS 隐藏顶部状态栏
- 改变Prompt默认路径,Change Default Visual Studio Command Prompt Location
- mysql 按指定id排序
- Ubuntu 14.10 server服务器版配置无线上网
- 小波变换图像处理
- duplicate symbols for architecture armv7解决办法
- 在ios9下,使用afnetworking执行http请求(http://apitest.XXX.com/Login),但是一直返回的是error
- 小马哥----高仿苹果6S A235刷机拆机图与开机界面图 真八核6735芯片 精仿系列机