经实验验证,修正对using namespace std的认识
备注①:name:符号。指的实体包括:变量、函数、类
备注②:认为全局命名空间也是一个包,在此称作 ROOT:: 或 global::
(这样就有了两个特别的包:一个是全局包,一个是std包。但对于编译器(pack-path. names模型)来说,它们和用户自定义的namespace没有区别)
修正1. global::(全局包)中的names,并不都是用户自定义的。
2. 两条重要认识,以及由此解释一些之前的问题
一、using namespace xxx; <—> using pack-A的本质作用: 相当于把 导入的Pack-A的 names 移到 using pack-A; 这行文字所在的那个namespace 的names空间里。
二、所有非ROOT 的namespace里 ,都已默认存在 using namespace :: (移入了ROOT包的 names ) ——> 所以才直接用全局的names
结论1:之前都是 "using namespace std "写在自定义namespace外,那么这行处在global::中,导致:把引进来的std::包里的names移到了 global包,成为全局的名字。
又因为各namespace已默认导入了global::names,所以这部分std::names进入了各namespace里。
导致的问题: 这样,当在wjh::内写某个name的定义时,若未加namespace-xxx::前缀而直接引用了 ‘fuck’,那么这个fuck可能有3处来源:
①wjh::fuck
②(global::) fuck
③namespace-ABC::fuck // 在全局(=namespace外部) 中using namespace ABC后, ABC::下的names进入全局空间,进一步进入wjh::
只要以上3个namespace里存在不止一个 fuck 这个name,就属于 ‘Ambiguous function call’ 报错。 (也可能不报错,但编译器会自己挑一个合适的用!)
不存在什么优先认定,3个中只能存在1个!
/*
* ↑ 修正:实验了一下,当不加包路径的 fuck存在上面①②③时,确实会选择①、编译器不提示报错。 所以同namespace的那个name确实是优先的
* 但当同namespace下无此name,②③是会冲突的。
*/
结论2:所以using namespace std; 为什么不能使用?
别人的模块引用了你的这个头文件后,多了这行字,原来未加namespace:: 引用的name只有一处定义,现在可能就多了个定义,
而编译器又不报错,就导致‘God knows what’种种奇特行为(因为引用的name被偷偷替换掉了)
写段实验代码验证一下以上认识:
前提:<test.h> : 定义一个global::fuckit(); 在namespace wjh{ }里也定义一个fuckit();
观察:此时在wjh{ } 中引用 fuckit() (不加wjh::),看是否提示
#ifndef _TRIAL_1_H
#define _TRIAL_1_H
int fuckit();
namespace wjh {
int fuckit();
}
#endif
在global::下使用如下 (该main位于global空间)
(using namespace wjh; 把 wjh::fuckit 这个name移入了global::中)
#include "trial-1.h" using namespace wjh; int main() {
::fuckit();
wjh::fuckit();
fuckit(); //报错! system("pause");
return ;
}
截图如下:
更进一步的实验:
#ifndef _TRIAL_1_H
#define _TRIAL_1_H // ③ s_t_d::fuckit
namespace s_t_d {
int fuckit();
} // ② (global::) fuckit
int fuckit(); // ① wjh::fuckit
namespace wjh {
using namespace s_t_d;
int fuckit();
void call_fuckit();
} #endif
#include "trial-1.h" #include <iostream>
#include <cstdlib> //using namespace s_t_d;
//using namespace wjh; int s_t_d::fuckit() {
std::cout << "s_t_d:: fuckit" << std::endl;
return ;
}
int fuckit() {
std::cout << "global:: fuckit" << std::endl;
return ;
}
int wjh::fuckit() {
std::cout << "wjh:: fuckit" << std::endl;
return ;
} void wjh::call_fuckit() {
using namespace s_t_d;
std::cout << "running in wjh:: calling fuckit ..." << std::endl;
fuckit();
} int main() {
wjh::call_fuckit(); fuckit(); system("pause");
return ;
}
最新文章
- C语言 01 形参实参
- 【Android】[转] Android Handler应设为static
- win8.1企业版 IIS8.5 安装php5.5.18详细图文
- delphi常用快捷键(我自己经常使用的)
- Synchronization in Delphi TThread class : Synchronize, Queue
- 【memcache缓存专题(2)】memcache安装与命令行使用
- Android自定义控件步骤总结
- iOS 沙盒目录结构介绍
- C#基础语法总结
- Vmware linux 安装 Vmware Tools 提示只读
- random_shuffle (stl算法)打乱顺序 - 飞不会的日志 - 网易博客
- windos环境apache+mysql+php+Discuz的安装配置
- JSON 解析工具的封装(Java)
- GIT入门笔记(3)- git中的一些概念和原理
- Python面向对象 组合(选课系统示例)
- rabbitMQ、activeMQ、zeroMQ、Kafka、Redis 比较
- 深入理解 Neutron -- OpenStack 网络实现(1):GRE 模式
- mysql 管理脚本
- 统计学习方法c++实现之七 提升方法--AdaBoost
- 20181101noip模拟赛T1
热门文章
- Nginx 反向代理功能-实现Nginx tcp负载均衡
- Linux操作系统安全-局域网私有CA(Certificate Authority)证书服务器实战篇
- 浅析Volatile关键字
- Python 实现基于信息熵的 ID3 算法决策树模型
- isaster(Comet OJ - Contest #11D题+kruskal重构树+线段树+倍增)
- Gartner:2019 年 iPaaS 魔力象限
- stm32定时器频率采样的方式
- 函数$f(x+1)$和$f(x-1)$的奇偶性
- GDAL在VS下配置测试
- Android Q Beta 6 终极测试版发布!