C++ 名称空间详情

目录
  • 一、传统的C++命名空间
  • 二、新的命名空间特性
    • 1.using声明和using编译指令
    • 2.名称空间的其他特性

一、传统的C++命名空间

声明区域(declaration region): 声明区域是可以在其中进行声明的区域。例如,可以在函数外面声明全局变量,对于这种变量,那么它的声明区域为其声明所在的文件。对于在函数中声明的变量,声明区域为其声明所在的代码块。
潜在作用域(potential scope): 变量的潜在作用域从声明点开始,到其声明区域的结尾。因此潜在作用域比声明区域小,这是由于变量在定义之后才能使用。

二、新的命名空间特性

C++包含了一种功能,即通过定义一种新的声明区域来创建命名的名称空间,这样做的目的之一是提供一个声明名称的区域。一个名称空间中的名称不会与另外一个名称空间的相同名称发生冲突,同时允许程序其他部分使用该名称空间中声明的东西。 例如,使用关键字namespace创建两个名称空间:

namespace Jack {
    double pail;                           // variable declaration
    void fetch();                          // function prototype
    int pal;                               // variable declaration
    struct Well {...}                      // structure declaration
}

namespace Jill {
    double bucket(double n) {...};         // variable declaration
    double fetch;                          // variable declaration
    int pal;                               // variable declaration
    struct Hill {...}                      // structure declaration
}

名称空间是开放的(open),即可以把名称加到已有的名称空间中。例如,下面这条语句将名称goose添加到Jill中已有的名称列表中:

namespace Jill {
    char* goose(const char*);
}

同样,原来的Jack名称空间为fech()函数提供了原型。可以在该文件后面(或者另一个文件中)再次使用Jack名称空间来提供函数的代码:

namespace Jack {
    void fetch() {
        ...
    }
}

需要访问给定名称空间的名称时,通过作用域解析运算符::,使用名称空间来限定该名称。

1.using声明和using编译指令

当我们不希望每次使用名称时都对它进行限定,因此c++提供了两种机制(using声明和using编译指令)来简化对名称空间中名称的使用。

using声明:使特定声明的标识符可用

namespace Jill {
    double bucket(double n) { ... }
    double fetch;
}
char fetch;

int main() {
    using Jill::fetch     // using declaration
    double fetch;         // Error! Already have a local fetch
    cin >> fetch;         // read a value into Jill::fetch
    cin >> ::fetch;       // read a value into global fetch
}

这段代码,using声明将特定的名称添加到它所属的声明区域中。main()中的using声明将fetch添加到main()定义的声明区域中。完成声明后,便可以使用名称fetch代替Jill::fetch

using编译指令:使整个名称空间可用

using编译指令使所有的名称都可用。在全局声明区域中使用using编译指令,将使该名称空间的名称全局可用。例如:

#include <iostream>
using namespace std;

// 在函数中使用using编译指令,将使其中的名称在函数中可用
int main() {
    using namespace jack;   // make names available in vorn()
}

不同的命名空间表示不同的内存单元,以下情况会存在二义性问题,使用时应该注意。

using namespace jack
using namespace jill   // 二者空间中都有pal变量

pal = 4;               // which one? now have a conflict

一般来说,使用using声明比使用using编译指令更安全,这是由于它只导入指定的名称。如果该名称与局部名称发生冲突,编译器会发出指示。using编译指令导入所有名称,包括一些实际并不需要的。如果与局部名称发生冲突,局部覆盖名称空间的版本,而编译器不会发出警告。

2.名称空间的其他特性

名称空间可以嵌套

namespace elements {
    namespace fire {
        int flame;
        ...
    }
    float water;
}

访问flame指的是elements::fire::flame,同样也可以使用using编译指令使内部的名称可用:using elements::fire

在名称空间中使用using编译指令和using声明,如下:

namespace myth {
    using Jill::fetch;
    using namespace elements;
    using std::count;
}

如果要访问Jill::fetch,以下两种方式均可访问它

myth::fetch
Jill::fetch

名称空间的传递性

using编译指令是可以传递的。如果A op B且B op C,则A op C。

using namespace myth;

/// 以上和下面两句等价
using namespace myth;
using namespace elements;

// 给命名空间创建别名
namespace MEF = myth::elements::fire;
using MEF::flame;

未命名的名称空间

往往是静态变量的替代品。

static int counts       //全局声明 static storage, internal linkage

/// 等价于
namespace {
    int counts          //  static storage, internal linkage
}

到此这篇关于C++ 名称空间详情的文章就介绍到这了,更多相关C++ 名称空间内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解C++数组和数组名问题(指针、解引用)

    目录 一.指针 1.1 指针变量和普通变量的区别 1.2 为什么需要指针 1.3 指针使用三部曲 二.整形.浮点型数组 2.1 数组名其实是特殊的指针 2.2 理解复杂的数组的声明 2.3 数组名a.数组名取地址&a.数组首元素地址&a[0].指向数组首元素的指针*p 2.4 对数组名以及取值符&的理解 三.字符数组数组名 一.指针 1.1 指针变量和普通变量的区别 指针:指针的实质就是个变量,它跟普通变量没有任何本质区别.指针完整的应该叫指针变量,简称为指针. 是指向的意思.指针

  • C++中模板和STL介绍详解

    目录 一.模板 1.1.函数模板 1.1.1.两种函数模板的实例化 1.1.2.模板参数的匹配原则 1.2.类模板 二.STL 总结 一.模板 对于一个交换函数,虽然C++支持函数重载,我们可以对多个交换函数起相同的名字: void Swap(int& left, int& right) { int temp = left; left = right; right = temp; } void Swap(double& left, double& right) { doub

  • C++设计一个简单内存池的全过程

    什么是内存池??? 通常我们用new或malloc来分配内存的话,由于申请的大小不确定,所以当频繁的使用时会造成内存碎片和效率的降低.为了克服这种问题我们提出了内存池的概念.内存池是一种内存分配方式.内存池的优点就是可以有效的减少内存碎片化,分配内存更快速,减少内存泄漏等优点. 内存池是在真正使用内存之前,先申请分配一个大的内存块留作备用.当真正需要使用内存的时候,就从内存池中分配一块内存使用,当使这块用完了之后再还给内存池.若是内存块不够了就向内存再申请一块大的内存块. 可以看出这样做有两个好

  • C++ ofstream和ifstream详细用法

    目录  一.stream类的两个重要的运算符 1.插入器(<<) 2.析取器(>>) 二.常见的文件操作 1.打开文件 2.关闭文件 3.读写文件 三.检测EOF 四.文件定位 五.输入和输出格式 1.整数数据的输入输出 2.字符数据的输入 3.字符串数据的输入 4. 浮点数 六. 二进制文件 七.随机存取文件 在C++中,有一个stream这个类,所有的I/O都以这个"流"类为基础的,包括我们要认识的文件I/O.  一.stream类的两个重要的运算符 1.插

  • C++中名称空间namespace的使用方法示例

    命名空间 在C++中,名称(name)可以是符号常量.变量.宏.函数.结构.枚举.类和对象等等.为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间/名字空间/名称空间/名域),可以更好地控制标识符的作用域. MFC中并没有使用命名空间,但是在.NET框架.MC++和C++/CLI中,都大量使用了命名空间. 我们常常会见到这样的语句: using namespace std; 或者还有这样的: usin

  • C++内存模型和名称空间详解

    目录 1. 单独编译 2.存储持续性.作用域和链接性 2.1 作用域和链接 2.2 自动存储持续性 2.3 静态持续变量 2.4 静态持续性.外部链接性 2.5 静态持续性.内部链接性 2.6 静态存储持续性.无链接性 2.7 说明符和限定符 2.8 函数和链接性 2.9 语言链接性 2.10 存储方案和动态分配 3. 名称空间 3.1 传统的C++名称空间 3.2 新的名称空间特性 3.3 名称空间及其前途 4 .总结 本章内容包括: 单独编译 存储持续性.作用域和链接性 定位new运算符 名

  • C++之OpenCV图像高光调整具体流程

    实现原理 PS中的高光命令是一种校正由于太接近相机闪光灯而有些发白的焦点的方法.在用其他方式采光的图像中,这种调整也可用于使高光区域变暗.要实现图像的高光调整,首先要识别出高光区:再通过对高光区的色彩进行一定变换,使其达到提光或者暗化效果:最后也是最重要的,就是对高光区和非高光区的边缘作平滑处理. 下方介绍具体流程. 具体流程 1)读取识别图像的原图,并转灰度图,再归一化. // 生成灰度图 cv::Mat gray = cv::Mat::zeros(input.size(), CV_32FC1

  • C++如何实现定长内存池详解

    目录 1. 池化技术 2. 内存池概念 2.1 内存碎片 3. 实现定长内存池 3.1 定位new表达式(placement-new) 3.2 完整实现 总结 1. 池化技术 池是在计算机技术中经常使用的一种设计模式,其内涵在于:将程序中需要经常使用的核心资源先申请出来,放到一个池内,由程序自己管理,这样可以提高资源的使用效率,也可以保证本程序占有的资源数量. 经常使用的池技术包括内存池.线程池和连接池(数据库经常使用到)等,其中尤以内存池和线程池使用最多. 2. 内存池概念 内存池(Memor

  • C++中的复制构造函数详解

    目录 复制构造函数 复制构造函数的三种调用 复制构造函数的禁用 深拷贝与浅拷贝 一定会生成默认复制构造函数吗? 参考 总结 普通变量的复制 有时我们会在定义一个变量的同时使用另一个变量来初始化它. int a_variable=12; int new_variable(a_variable); 通过已有的同类型变量来初始化自身很有用. 对自定义类型的对象是否可以通过一个存在的对象方便的复制呢? 复制构造函数 复制构造函数又叫做拷贝构造函数,它只有一个参数(既然需要复制,一个就够了,若传入两个相同

  • C++ 名称空间详情

    目录 一.传统的C++命名空间 二.新的命名空间特性 1.using声明和using编译指令 2.名称空间的其他特性 一.传统的C++命名空间 声明区域(declaration region): 声明区域是可以在其中进行声明的区域.例如,可以在函数外面声明全局变量,对于这种变量,那么它的声明区域为其声明所在的文件.对于在函数中声明的变量,声明区域为其声明所在的代码块. 潜在作用域(potential scope): 变量的潜在作用域从声明点开始,到其声明区域的结尾.因此潜在作用域比声明区域小,这

  • python 名称空间与作用域详情

    目录 一.名称空间 1.1 内置名称空间 1.2 全局名称空间 1.3 局部名称空间 1.4 加载顺序 1.5 查找顺序 二.作用域 2.1 全局作用域 2.2 局部作用域 2.4 函数对象+作用域应用 三.补充知识点 3.1 global关键字 3.2 nonlocal关键字 3.3 注意点 函数内部的函数只能在函数内部调用,不能在函数外部调用,通过接下来的学习你将会知道为什么会出现这种情况. 一.名称空间 名称空间(name spaces):在内存管理那一章节时,我们曾说到变量的创建其实就是

  • python 名称空间与作用域详情

    目录 一.名称空间 1.1 内置名称空间 1.2 全局名称空间 1.3 局部名称空间 1.4 加载顺序 1.5 查找顺序 二.作用域 2.1 全局作用域 2.2 局部作用域 2.4 函数对象+作用域应用 三.补充知识点 3.1 global关键字 3.2 nonlocal关键字 3.3 注意点 函数内部的函数只能在函数内部调用,不能在函数外部调用,通过接下来的学习你将会知道为什么会出现这种情况. 一.名称空间 名称空间(name spaces):在内存管理那一章节时,我们曾说到变量的创建其实就是

  • Spring根据XML配置文件 p名称空间注入属性的实例

    要生成对象并通过名称空间注入属性的类 代码如下: package com.swift; public class User { private String userName; public void setUserName(String userName) { this.userName = userName; } public String fun() { return "User's fun is ready."+this.userName; } } XML配置文件写法如下: &

  • 实例详解python函数的对象、函数嵌套、名称空间和作用域

    函数的对象 python中一切皆对象 函数对象的四大功能 引用 def f1(): print('from f1') f1() #调用函数 print(f1) print('*'*50) f = f1 # 将函数名f1赋值给f f() # f也可以调用函数 print(f) from f1 <function f1 at 0x000001FB05534620> ************************************************** from f1 <func

  • 一篇文章搞懂Python的类与对象名称空间

    代码块的分类 python中分几种代码块类型,它们都有自己的作用域,或者说名称空间: 文件或模块整体是一个代码块,名称空间为全局范围 函数代码块,名称空间为函数自身范围,是本地作用域,在全局范围的内层 函数内部可嵌套函数,嵌套函数有更内一层的名称空间 类代码块,名称空间为类自身 类中可定义函数,类中的函数有自己的名称空间,在类的内层 类的实例对象有自己的名称空间,和类的名称空间独立 类可继承父类,可以链接至父类名称空间 正是这一层层隔离又连接的名称空间将变量.类.对象.函数等等都组织起来,使得它

  • python函数参数,名称空间,以及函数嵌套

    目录 一. 函数参数–动态传参 1.1动态位置接受参数,在参数位置编写*表⽰示接收任意内容 1.2 动态接收关键字参数 1.3无敌传参 * args, * * kwargs 一起使用 1.4 动态参数的另⼀一种传参⽅方式: 二. 命名空间 三. 函数的嵌套 四. 关键字global和nonlocal 一. 函数参数–动态传参 1.1动态位置接受参数,在参数位置编写*表⽰示接收任意内容 注意: 动态参数与位置参数的关系 默认参数和动态参数的关系 小结: 顺序: 位置参数, 动态参数*, 默认值参数

  • C++名称空间介绍

    目录 1.名称空间 1.1传统C++名称空间 1.2新的名称空间特性 1.名称空间 在C++当中,名称可以是变量.函数.结构体.枚举.类以及结构体和类的成员.这本身并没有问题,但随着项目的增大,名称之间相互冲突的可能性也会大大增加. 比如我们使用了多个厂商的代码,它们都定义了List,Tree和Node类,但定义的方式不同,也就没办法互相兼容.这个时候当我们希望使用一个库的List类,而使用另外一个的Tree类,就会非常麻烦.这类冲突被称为名称空间(namespace)问题. 1.1传统C++名

随机推荐