c++基础(namespace)
来源:zidea     阅读:553
源码超市
发布于 2019-06-11 03:41
查看主页
Cplusplus-tutorial-in-hindi.jpg

有关namespace也称命名空间,想必大家并不默认,通过增加命令空间来处理同一结构函数的冲突的问题,我们

#include <iostream>#include <string>void print(const char *text){    std::cout << text << std::endl;}void print(const char *text){    std::cout << text << std::endl;}int main(int argc, char const *argv[]){    std::cin.get();}

编译源码报错表示我们重新定义了 print 函数,在 c++ 中具每一个函数都是对应一个 Symbol ,这个 Symbol 是可以表示 class、function 或者是 variable。由于这个两个 print结构和名称一致,这里结构就是我们定义函数的形参和返回值类型都是相同。在 c++ 中 symbol 是唯一,所以编译时候报下面的错误。
最简单最粗暴就是修改函数名 a_print 和 b_print。不过多数情况我们是和第三方库同名,无法修改库中函数名称。这时候我们即可以使用到命名空间来处理 symbol 冲突的问题。

这里在多说依据在 c 语言中是不支持命名空间的,所以我们看 openGL 的库函数都有前缀 gl_ 通过这种方式进行区分。

namespace2.cpp:9:6: error: redefinition of 'print'void print(const char *text)     ^namespace2.cpp:4:6: note: previous definition is herevoid print(const char *text)

在 c++ 中我们可以使用命名空间来对两个相同 symbol 的函数进行区分来处理冲突问题。

namespace A{void print(const char *text){    std::cout << text << std::endl;}} // namespace Anamespace B{void print(const char *text){    std::cout << text << std::endl;}} 

使用时候可以通过::操作符来调用 namespace A 的 print 方法。在调用 class 的静态方法时候我们也可能会用到:: 操作符,这是由于 class 本身就提供一个命名空间。

A::print("hello");

namespace 支持嵌套。

namespace A{namespace functions{void print(const char *text){    std::cout << text << std::endl;}} // namespace functions} // namespace A
A::functions::print("hello");

将我们命名空间使用缩小的一个作用域可以在function内也可以在{}定义作用域

    using namespace A;    functions::print("hello");    std::cin.get();
    using B::print;    print("hello");    B::another_print();

假如只想使用命名空间来简化对Bprint调用,而不涉及 another_print,即可以这样来写。

    namespace second = B;    second::print("hello");    B::another_print();

也可以为命名空间起一个别名namespace second = B;

大家习惯会用 namespace 来简化每次都需要输入std的工作.

#include <iostream>#include <vector>#include <algorithm>#include <functional>void ForEach(const std::vector<int> &values, const std::function<void(int)> &func){    for (int value : values)        func(value);}int main(int argc, char const *argv[]){    std::vector<int> values = {1, 2, 3, 2, 1};    auto it = std::find_if(values.begin(), values.end(), [](int value) { return value > 2; });    std::cout << *it << std::endl;    int a = 5;    auto lambda = [=](int value) mutable { a= 6; std::cout << "value: " << a << value << std::endl; };    ForEach(values, lambda);    std::cout << a << std::endl;    std::cin.get();}

上面的代码我们每次引用std都会写std::,假如使用using namespace std;我们就无需在每一个 std 提供方法前写std::using namespace有肯定的作用域。

假如我们使用using namespace来简化函数调用前缀,当然对于一个简单项目没有问题,这是好事减少我们输入,但是假如是一个引用第三方库或者这些写许多和标准库同名函数,我们就应该避免使用using namespace ,这样做会让我们和其余阅读代码人 confusing ,这个函数出处。

#include <iostream>#include <string>namespace apple{void print(const std::string &text){    std::cout << text << std::endl;}} // namespace applenamespace orange{void print(const char *text){    std::string temp = text;    std::reverse(temp.begin(), temp.end());    std::cout << temp << std::endl;}} // namespace orangeusing namespace apple;// using namespace orange;int main(int argc, char const *argv[]){    print("Hello");    std::cin.get();}
Hello

同时存在两个 namespace 时候,会调用谁的print函数呢?

using namespace apple;using namespace orange;

看结果调用的是 orange 的 print

olleH

为什么呢,这要从"Hello"究竟是什么类型来说起,"Hello" 是 char* 的类型,在没有orangeprint的时候,会调用 applevoid print(const std::string &text),这里是隐式将char*转换为 std::string 类型,但是一旦有了rangeprint 函数由于其参数类型 const char*"hello" 匹配更好所以执行了orangeprint而不是 appleprint

但是不是表明我们不使用 using namespace ,存在就意义,在自己的库中是可以使用 using name

免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 系统环境 服务器应用
相关推荐
js、jq获取兄弟节点,父节点,子节点
查看SharedPreferences中保存的数据
Java实现SQL语句多条件模糊查询
iOS电商常见动画与布局、微信悬浮窗、音乐播放器、歌词解析、拖动视图等源码
【Java进阶面试系列之二】:哥们,那你说说系统架构引入消息中间件有什么缺点?
首页
搜索
订单
购物车
我的