当前位置: 首页 > news >正文

Cherno C++ P60 为什么不用using namespace std

这篇文章我们讲一下之前写代码的时候的一个习惯,也就是不使用using namespace std。如果我们接触过最早的C++教程,那么第一节课都会让我们写如下的代码:

#include<iostream>

using namespace std;

int main() {
    cout << "Hello World!" << endl;
    cin.get();
}

非常经典的入门代码。同样也使得using namespace std这句话深入人心了。但是如果我们看之前教程里面的代码,基本上清一色都是不用using而是直接把std写出来,如下所示:

#include<iostream>

int main() {
    std::cout << "Hello World!" << std::endl;
    std::cin.get();
}

那么问题就来了,为什么我们不使用using namespace std?这样可以省去很多写std::的麻烦,不是么?但是实际上我们不建议这样使用。

我们在使用std::的时候,其实表明的含义是这些是来源于一个名为std的命名空间。如果有一个很长的命名空间或者是自己的命名空间,也许我们可以这样使用。但是对于std来说,写一下std::并不是一件麻烦的事情,但是这样可以很清晰地表明我们这些函数/类是来自于std命名空间内的,所以这是一件很有利的事情。如果没有std::,那我们就无法判断这些个函数变量来源于哪个命名空间,也许我们可以以变量的命名书写规则来进行区分,但是书写风格有的时候其实也是会撞车的。就比如Cherno所在的EA有开发自己的EASTL,命名方式是完全一样的,这个就会带来麻烦和困扰。

我们可以举一个简单的例子来说明如果不指明namespace,会带来哪些问题:

#include<iostream>
#include<string>
#include<algorithm>

namespace Apple {
    void Print(const std::string& str) {
        std::cout << str << std::endl;
    }
}

namespace Orange {
    void Print(const char* str) {
        std::string str_r = str;
        std::reverse(str_r.begin(), str_r.end());
        std::cout << str_r << std::endl;
    }
}

int main() {
    using namespace Apple;
    using namespace Orange;
    Print("HelloWorld");
    std::cin.get();
}

如上所示,我们定义了两个namespace,都是简单的打印函数,其中Orange是反向打印,而Apple是正向打印。我们同时采用using namespace然后看看会发生什么:

很神奇,我们的程序选择了Orange当中的打印。没有发生编译错误,但是运行结果并不一定是我们想要的。这个是因为什么?因为我们输入的对象是一个const char*类型的变量,虽然Apple当中的Print其实也能用,但是它需要进行一次隐藏的类型转换,转换为std::string,那么和Orange当中的Print一比较,编译器就会选择不需要类型转换的Orange当中的函数了。

所以如果我们想要准确的标明我们使用的是哪个命名空间里面的函数,肯定最好写成Orange::或者是Apple::了,但是如果非得就不想这么写行不行呢?也可以,如下所示:

using Apple::Print;
Print("HelloWorld");

这样写的话,那么我们在本作用域内所有的Print就都是Apple当中的Print了。

但是需要注意的一点是,在使用using namespace的时候,一定一定要控制using的适用范围,在一个小作用域内,或者是在一个文件里那是最好不过的。所以千万千万不要把using namespace写到头文件当中!如果这样的话,经过多轮的头文件来回包含,很有可能会导致我们都不知道我们用的是哪个namespace当中的函数了,从而引发代码的错误。所以千万千万不要这样用!

好了以上就是本文的全部内容了,希望大家喜欢!

相关文章:

  • Golang的图形用户界面设计
  • 网络编程——TCP
  • 微信小程序接入DeepSeek模型(火山方舟),并在视图中流式输出
  • 03 HarmonyOS Next仪表盘案例详解(二):进阶篇
  • 浏览器多实例项目的隔离方案
  • (十 七)趣学设计模式 之 状态模式!
  • 【前端】JavaScript 备忘清单(超级详细!)
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_read_token - 详解(3)
  • 云原生周刊:基于 KubeSphere LuBan 架构打造DeepSeek 插件
  • CSDN博客写作教学(五):从写作到个人IP的体系化构建(完结篇)
  • 【AD】4-8 AD集成库的创建与安装
  • C# 多线程
  • 【JAVA】ThreadPoolTaskExecutor 线程池学习、后端异步、高并发处理
  • 全星 FMEA 软件系统在芯片半导体行业的应用介绍
  • leetcode 56. 合并区间
  • abseil-cpp:环境搭建
  • css3d放置的面板方向不对问题排查
  • 二、QT和驱动模块实现智能家居-----问题汇总1
  • 期权帮|股指期货3月合约交割该如何做?
  • 【华为OD机试真题29.9¥】(E卷,100分) - TLV解码(Java Python JS C++ C )
  • 重庆动物园大熊猫被游客扔玻璃瓶,相同地方曾被扔可乐瓶
  • 韩国法院将李在明所涉案件重审日期延至大选后
  • 大规模空袭也门一日后,以军又对也门萨那机场发出撤离警告
  • 胡祥|人工智能时代:文艺评论何为?
  • 牛市早报|“五一”假期预计跨区域人员流动量累计14.67亿人次
  • 立夏的野火饭