IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 双冒号以及命名空间 -> 正文阅读

[C++知识库]C++ 双冒号以及命名空间

1、双冒号

1.1 作为作用域解析运算符

#include <iostream>
class my_class{
public:
    static void say(){
        std::cout << "hello my_class" << std::endl;
    }
};

namespace my_space{
    void say(){
        std::cout << "hello my_space" << std::endl;
    }
}

int main() {
    my_class::say();
    my_space::say();
    return 0;
}

如上方代码16行和17行所示,分别调用my_class类内和my_space名称空间内的say()函数。

1.2 表示默认全局命名空间内的函数或变量

#include <iostream>

//在全局命名空间中定义了一个变量global_char,和一个函数say()
char test_char = 'a';
void say(){
    std::cout << "hello global" << std::endl;
}

namespace my_space{//定义了一个名称空间my_space
    //名称空间内定义了一个函数say()和一个类my_class
    char test_char = 'b';
    void say(){
        //引用::global_char,表示去global namespace中寻找global_char
        std::cout << "全局的test_char为:" << ::test_char << std::endl;
        std::cout << "my_space的test_char为:" << test_char << std::endl;
    }

    class my_class{
    public:
        static void say(){
            std::cout << "hello my_class" << std::endl;
            ::say();//调用全局命名空间中的say()
        }
    };
}

int main() {
    my_space::my_class::say();//引用my_class中的静态成员函数say()
    my_space::say();
    say();      //默认调用全局命名空间中的say()
    ::say();	//调用全局命名空间中的say()
    return 0;
}

::say()意味着要去全局命名空间内寻找say()函数。
my_class类中的静态成员才能以双冒号解析的方式引用。

2、命名空间namespace

一个大型的程序通常由不同模块构成,不同模块甚至可能是由不同人员开发的。不同模块中的类和函数之间可能会发生重名,这样就会引发错误。这就好像上海和武汉都有南京路,如果在缺乏上下文的情况下直接说出“南京路”就会产生歧义。但如果说“上海的南京路”或者“武汉的南京路”,歧义就会消除。命名空间起到的就是这样的作用。

2.1 全局命名空间

全局命名空间是默认的命名空间,所有声明的命名空间之外声明的标识符都在全局命名空间中。
main()函数必须在全局明明空间中,也就是说,与main()并列的标识符都是全局命名空间中的标识符。

2.2 匿名命名空间

匿名命名空间是一个需要显式声明但是没有名字的命名空间,声明方式如下

namespace{
	匿名命名空间内的各种声明
}

匿名命名空间常被用来屏蔽不希望暴露给其他源文件的标识符。因为每个源文件的匿名命名空间是彼此把不同的,在一个源文件中没有办法访问其他源文件的匿名命名空间。

2.3 using指令

using指令有两种用法,一种是例如using namespace std的using编译指令,还有一种是例如using std::cin的using声明指令。

2.3.1 using声明指令

使用using声明指令后,被声明的标识符可以不用加域解析运算符直接引用。

#include "iostream"

using std::cin;

int main(){
    char ch;
    cin >> ch;//被声明的标识符可以直接引用
    std::cout << ch <<std::endl; //未被声明的标识符仍需加域解析符引用
    return 0;
}

2.3.2 using编译指令

using编译指令相当于将其所在作用域中所有的标识符,自动加上域解析符

#include "iostream"

using namespace std;

int main(){
    char ch;
    cin >> ch;
    cout << ch <<endl;
    return 0;
}

如上述代码所示,一旦找到某未在当前作用域内声明的标识符,编译器就会再去using namespace后声明的命名空间内寻找该标识符,一旦找到,就会自动在该标识符前面加上域解析符。于是上述代码就变成了

#include "iostream"

int main(){
    char ch;
    std::cin >> ch;
    std::cout << ch <<std::endl;
    return 0;
}

3、进阶

#include "iostream"
//在全局命名空间中使用了using编译指令
using namespace std;

namespace Jill{
    double bucket(double n);
    void fetch(){
    //在Jill命名空间中可以使用std中的名称
        cout << "hello Jill" << ::endl;
    }
    struct hill{ int name; };
}


int main(){
   Jill::hill a;
   Jill::fetch();
   ::cout << "hello world"<<endl;

   return 0;
}

需要注意的是第8行::endl和第17 行::cout表示去全局命名空间中寻找endlcout,然而全局名称空间中没有定义这两个标识符,所以编译器就去std中寻找他们,找到后就自动在前面加上了域解析符。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:30:29  更:2022-03-21 20:31:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:14:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码