• 第十八章 用于大型程序的工具
    • 命名空间
      • 命名空间定义
      • 每个命名空间都是一个作用域
      • 命名空间可以是不连续的
      • 使用命名空间成员
      • 友元声明与实参相关的查找
    • 虚继承

第十八章 用于大型程序的工具

命名空间

大型程序往往会使用多个独立开发的库,而这些库又会定义大量的全局名字,如类、函数和模板等。当应用程序用到多个供应商提供的库时,不可避免地回繁盛某些名字相互冲突地情况。多个库将名字放置在全局命名空间中将引发命名空间污染( namespace pollution )

命名空间( namespace ) 为防止名字冲突提供了更加可控的机制。

命名空间定义

一个命名空间的定义包括两部分:首先是关键字 namespace,随后是命名空间的名字。在命名空间名字后面是一系列由花括号括起来的声明和定义。只要能出现在全局作用域中的声明就能置于命名空间内。

namespace cplusplus_primer{class Sales_data{ /* ... */ };Sales_data operator+(const Sales_data&, const Sales_data&);class Query { /* ... */ };class Query_base { /* ... */ };
}   // 命名空间结束后无须分号

每个命名空间都是一个作用域

cplusplus_primer::Query q = cplusplus_primer::Query("hello");

如果其他命名空间(比如 AddisonWesley )也提供了一个名为 Query 的累,并且我们希望使用这个累代替 cplusplus_primer 中定义的同名类:

AddisonWesley::Query q = AddisonWesley::Query("hello");

命名空间可以是不连续的

命名空间可以定义在几个不同的部分。编写如下的命名空间定义:

namespace nsp{// ...
}

可能是定义了一个名为 nsp 的新命名空间,也可能是为已经存在的命名空间添加一些新的成员

命名空间的定义可以不连续的特性使得我们可以将几个独立的接口和实现文件组成一个命名空间。此时,命名空间的组织方式类似于我们管理自定义类及函数的方式:

  • 命名空间的一部分成员的作用是定义类,以及声明作为类接口的函数及对象,则这些成员应该置于头文件中,这些头文件将被包含在使用了这些成员的文件中
  • 命名空间成员的定义部分则只与另外的源文件中

使用命名空间成员

namespace_name::member_name 这样使用命名空间的成员显然非常繁琐。

命名空间的别名

namespace cplusplus_primer { /* ... */ }namespace primer = cplusplus_primer;// 命名空间的别名也可以指向一个嵌套的命名空间
namespace Qlib = cpluscplus_primer::QueryLib;
Qlib::Query q;

using 声明:扼要概述

一条 using 声明 语句一次只引入命名空间的一个成员。

using 声明引入的名字遵守与过去一样的作用域规则:它的有效范围从 using 声明的地方开始,一直到 using 声明所在的作用域结束为止。

// 命名空间 A 和函数 f 定义在全局作用域中
namespace A{int i, j;
}
void f(){using namespace A;cout << i * j << endl;   // 使用命名空间 A 中的 i 和 j// ...
}

using 指示示例

namespace blip{int i = 16, j = 15, k = 23;
}
int j = 0;
void manip(){// using 指示, blip 中的名字被“添加”到全局作用域中using namespace blip; // 如果使用了 j,则将在 ::j 和 blip::j 之间产生冲突++i;                   ++j;                  // 二义性错误++::j;                    // 正确:将全局的 j 设定为1++blip::j;                // 正确:将 blip::j 盛鼎为16int k = 97;                // 当前局部的 k 隐藏了 blip::k++k;                    // 将当前局部的 k 设定为 98
}

友元声明与实参相关的查找

当类声明了一个友元时,该友元声明并没有使得友元本身可见。然而,一个另外的为生命的类或函数如果第一次出现在友元声明中,则我们认为它是最近的外层命名空间的成员。

namespace A{class C{// 两个友元,在友元声明之外没有其他的声明// 这些函数隐式地称为命名空间 A 的成员friend void f2();         // 除非另有声明,否则不会被找到friend void f(const C&);    // 根据实参相关的查找规则可以被找到};
}
// 此时,f 和 f2 都是命名空间 A 的成员。即使 f 不存在其他声明,
// 也能通过实参相关的查找规则调用 f
int main(){A::C cobj;f(cobj);       // 正确:通过在 A::C 中的友元声明找到 A::ff2();            // 错误: A::f2 没有被声明
}

虚继承

C++ 通过 虚继承 virual inheritance 的机制解决菱形继承的问题:虚继承的目的是令某个类做出声明,承诺愿意共享它的基类。其中,共享的基类子对象称为虚基类。在这种机制下,布鲁虚基类在继承体系中出现了多少次,在派生类中都只包含唯一一个共享的虚基类子对象

《C++11Primer》阅读随记 -- 十八、用于大型程序的工具相关推荐

  1. 《C++Primer》第十八章 用于大型程序的工具

    第十八章 用于大型程序的工具 异常处理 1. 抛出异常 在C++语言中,我们通过抛出throwing一条表达式来引发raised一个异常.当执行一个throw时,跟在throw后面的语句将不再被执行. ...

  2. C++ primer第二次阅读学习笔记(第17章:用于大型程序的工具:命名空间)

    第十七章:用于大型程序的工具:命名空间 在一个给定的作用域中定义的每个名字,在该作用域中必须是唯一的.对庞大.复杂的应用程序而言,这个很难满足.由独立开发的库构成的复杂程序更有可能遇到名字冲突,因为库 ...

  3. C++ Primer 18 用于大型程序的工具

    用于大型程序的工具 大规模编程对程序设计语言的要求更好.大规模应用程序的特殊要求包括: 在独立开发的子系统之间协同处理错误的能力. 使用各种库(可能包含独立开发的库)进行协同开发的能力. 对比较复杂的 ...

  4. c++ primer 18th 用于大型程序的工具

    一.异常处理 抛出异常 当执行一个throw时,跟在throw后面的语句将不再执行.相反,程序的控制权从throw转移到与之匹配的catch模块.该catch可能是同一个函数的局部catch,也可能位 ...

  5. 【C++ Primer】第18章 用于大型程序的工具 (3)

    Part IV: Advanced Topics Chapter 18. Tools for Large Programs 18.3 多重继承与虚继承 多重继承 (multiple inheritan ...

  6. C语言编程>第十八周 ⑧ 给定程序中,函数fun的功能是:将形参指针所指结构体数组中的三个元素按num成员进行升序排列。

    例题:给定程序中,函数fun的功能是:将形参指针所指结构体数组中的三个元素按num成员进行升序排列. 注意:请勿改动主函数main与其他函数中的任何内容,仅在横线上填写所需的若干表达式或语句. 代码如 ...

  7. 摄影获得最佳图像的十大要诀_十大最佳应用程序性能管理工具

    摄影获得最佳图像的十大要诀 Looking for Application Performance Management (APM) tools for your organization? Here ...

  8. 论文阅读笔记二十八:You Only Look Once: Unified,Real-Time Object Detection(YOLO v1 CVPR2015)...

    论文源址:https://arxiv.org/abs/1506.02640 tensorflow代码:https://github.com/nilboy/tensorflow-yolo 摘要 该文提出 ...

  9. 分布式系统阅读笔记(十八)-----副本备份技术

    介绍 在分布式系统中,副本和备份是一个用来提供高可用性和一定的容错能力的手段和措施.HA(高可用性)在当前越来越成为一个趋势在一些移动计算的领域和一些失去连接的状态场景之下.在这篇笔记中,我会介绍一些 ...

最新文章

  1. 生活随笔[2005-06-08]
  2. java学习笔记9--内部类总结
  3. java 连接janusgraph_基于JanusGraph的大数据图数据库
  4. 【Linux网络编程】并发服务器的三种实现模型
  5. python精确计时_PYTHON在WINDOWS下高精度计时的体会
  6. Ubuntu 为普通用户添加sudo权限
  7. java properties native2ascii_properties文件国际化之native2ascii
  8. PLSQL导出表结构
  9. 天津智慧路灯+“新基建”示范区建设启动、沪苏通长江公铁大桥
  10. c语言投票系统程序,C语言智能投票系统.doc
  11. python代码加密解密_Python实现对字符串的加密解密方法示例
  12. java天才_哪个天才写的?太精辟了
  13. IKBC键盘win键失灵解决方法
  14. java实现图片的压缩且保留图片尺寸不变
  15. 如何把身份证扫描成电子版?证件转电子版,这3个方法超好用
  16. 文件的元数据信息的含义及查看和修改
  17. 关于手持设备PDA的开发
  18. 详解网络层协议(ICMP,ARP)
  19. excel表格换行快捷键_常州办公excel表格常用技巧, 办公软件常用快捷键【金坛吧】...
  20. 管理系统菜单父子结构,有parentId,快速获取结构树代码

热门文章

  1. Java多线程之队列Quene-yellowcong
  2. 火狐64版本禁止自动更新提示方法
  3. typeinfo、typeid、 typeof 介绍
  4. ArcMap中面要素生成Voronoi图(V图)或者泰森多边形
  5. 严选114个创新创意Java计算机毕业设计项目,赢在毕设起跑
  6. C++LNK2001
  7. fp32/bfp16数据类型
  8. 将txt格式的模型转换为bin格式
  9. [Machine Learning] 线性回归
  10. 题目: =====i am biter逆置为: biteram i函数原型: