【C++ 記憶站】命名空間

在這里插入圖片描述

文章目錄

    • 命名空間概念
      • 命名空間的定義
        • 1、正常的命名空間定義
        • 2、命名空間可以嵌套
        • 3、同一個工程中允許存在多個相同名稱的命名空間,編譯器最后會合成同一個命名空間中
      • 命名空間的使用
        • 1、加命名空間名稱及作用域限定符
        • 2、使用using將命名空間中某個成員引入
        • 3、使用using namespace 命名空間名稱 引入
        • 4、使用using namespace std C++標準庫命名空間 引入

在這里插入圖片描述

命名空間概念

在C/C++中,變量、函數和后面要學到的類都是大量存在的,這些變量、函數和類的名稱將都存 在于全局作用域中,可能會導致很多沖突。使用命名空間的目的是對標識符的名稱進行本地化, 以避免命名沖突或名字污染,namespace關鍵字的出現就是針對這種問題的。

很多人在開始接觸C++的時候,知道打印一行 hello world 都是這樣寫的:

#include
using namespace std;
int main()
{
cout << “hello world” << endl;
}

但是要問你iostream 和 namespace std 是什么,在這行代碼中起到什么作用,很多初學者基本上是回答不上來的,就知道怎么寫,不知道其中的意義。

那么現在就開始認識命名空間這個概念
大家都知道C++是在c語言基礎上建立的,c語言很多地方存在很多缺陷的,C++就創建了一個命名空間的概念來彌補這一缺陷
這一缺陷是什么呢?創建一個全局變量 int rand = 0 ,你只引入了頭文件 <stdio.h> ,利用printf打印出rand,不會產生任何問題。可當你再引用了 <stdlib.h> ,再次運行程序就會出現問題
在這里插入圖片描述
這里報錯,顯示rand重定義,這里的問題叫做命名沖突,因為 stdlib.h 這個庫里面已經定義了rand,且定義成的一個函數,而我們這個全局變量rand是int類型的元素,系統在識別這個rand的時候就會找到兩個rand,它不知道去打印哪一個,當然這里剛好rand在庫里面是個函數 且與%d發生沖突,顯示兩個錯誤

在c語言中,解決這一問題,最簡單粗暴的方法,就是改變量名稱,防止與庫里面的同名變量命名沖突,這樣當然可以解決問題,但如果你在一個團隊中需要分組完成一個項目,每個組的個別變量都一樣,這時候怎么辦,總不能組與組直接吵一架吧,這會大大降低工作效率不說,也影響團隊氛圍嘛,所以顯然這種方法不可取。

在這里插入圖片描述
既然c語言不能解決這個問題,那么C++就提出了命名空間來解決
這里就要引入一個關鍵字 namespace ,它的作用是創建一個域把創建的rand變量保護起來,下面是代碼實現

namespace Yuan
{int rand = 0;
}
int main()
{printf("%d\n", rand);
}

namespace 后面的名字隨便取什么都行,只要自己記得住
這樣就不會產生命名沖突的問題,main里面打印的是庫函數里面的rand(準確來說是訪問全局的域來找到rand),并不是Yuan里面的rand
要想打印Yuan里面的rand需要在rand前面加Yuan::

namespace Yuan
{int rand = 0;
}
int main()
{printf("%d\n", Yuan::rand);
}

namespace創建的是一個命名為Yuan的局部域,這里需要回顧一下C語言里面的全局變量和局部變量

int i = 0;
int main()
{int i = 1;printf("%d", i);
}

現在問大家一個問題,這里打印的i是0還是1?

答案是1,這里滿足一個就近原則,打印結果是1,這里是直接訪問的局部域里面的局部變量i

但是如果你想在局部域里面訪問全局變量i,怎么辦?

需要在i前面加::

int i = 0;
int main()
{int i = 1;printf("%d\n", ::i);printf("%d\n", i);
}

::叫做域作用符,作用是指定在哪個域里面去找這個i,這里::左邊是空白,就代表在全局域里面去找

在這里插入圖片描述

所以命名沖突問題有了命名空間這個概念,就迎刃而解了。A B C三個小組,每個小組寫的所有的變量全都保存在他們自己所定義的命名空間里面,且命名空間分別交nodeA nodeB nodeC,即使各自的命名空間里面有相同的變量,也不會收到任何影響

命名空間的定義

1、正常的命名空間定義

命名空間里面可以定義變量,函數,類型等

namespace Yuan
{int rand = 0;void func(){printf("func()\n");}struct TreeNode{struct TreeNode* left;struct TreeNode* right;int val;};
}int main()
{printf("%p\n", rand);printf("%p\n", Yuan::rand);Yuan::func();struct Yuan::TreeNode node;return 0;
}

2、命名空間可以嵌套

命名空間可以嵌套,就想循環語句一樣

namespace sql
{int a = 0;namespace Yuan{int rand = 0;void func(){printf("func()\n");}struct TreeNode{struct TreeNode* left;struct TreeNode* right;int val;};}
}int main()
{printf("%p\n", rand);printf("%p\n", sql::Yuan::rand);sql::Yuan::func();struct sql::Yuan::TreeNode node;return 0;
}

3、同一個工程中允許存在多個相同名稱的命名空間,編譯器最后會合成同一個命名空間中

這一點怎么來理解呢,比如說在一個項目中我們添加了Stack.h(棧),Stack.cpp(棧),Queue.h(隊列),Queue.cpp(隊列),里面有很多變量,類型,函數等,現在要把它們放到一個命名空間里面,我們會擔心發生命名沖突的問題,怎么處理呢?
這四個文件中分別定義一個 每次為 Yuan 的命名空間,并把文件中所有東西放到命名空間中,這四個命名空間名字相同,但不在一個文件中,編譯器會自動把它們合并到一個命名空間中,不用擔心命名沖突的問題

namespace Yuan
{typedef int STDataType;typedef struct Stack{STDataType* a;int top;		// 棧頂的位置int capacity;	// 容量}ST;
}#include "Stack.h"//棧
#include "Queue.h"//隊列int main()
{Yuan::ST st;Yuan::StackInit(&st);Yuan::Queue q;Yuan::QueueInit(&q);
}

命名空間的使用

1、加命名空間名稱及作用域限定符

int main()
{printf("%d\n", Yuan::a);return 0;  
}

前面已經介紹了通過域作用符來進行命名空間的使用,這也是最基本最簡單的一種命名空間使用方式,可這個方式如果在命名空間使用比較多的時候就顯得有些繁瑣了,可能這里沒有加域作用符,那里又沒有加,導致一堆bug,所以就有了以下三種方式

2、使用using將命名空間中某個成員引入

using Yuan::b;
int main()
{printf("%d\n", Yuan::a);printf("%d\n", b);return 0;  
}

3、使用using namespace 命名空間名稱 引入

using namespce N;
int main()
{printf("%d\n", Yuan::a);printf("%d\n", b);Add(10, 20);return 0;  
}

4、使用using namespace std C++標準庫命名空間 引入

前面兩種相對就比較保守,這個就是很大膽的直接展開C++全部標準庫,雖然是很大程度上避免了一定的沖突,但是這樣全部展開,就可能存在沖突的風險,所以直接全部展開不推薦使用,如果要用應該是這樣寫

#include<iostream>
//using namespace std
int main()
{std::cout << "hello world" << std::endl;return 0;
}

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41832.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41832.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41832.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

初試時間官宣!研招網發布下半年重要時間節點!今日速報來了

距24考研初試還有127天&#xff0c;今天給大家帶來初試和報名時間官宣消息、考研報名注意事項、研招網發布的2024考研“保姆級”下半年重要時間節點。有用記得收藏 24考研報名和初試時間官宣 已有學校在招生簡章中明確24考研初試時間 初試時間預計為&#xff1a;2023年12月23…

初試rabbitmq

rabbitmq的七種模式 Hello word 客戶端引入依賴 <!--rabbitmq 依賴客戶端--><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.8.0</version></dependency> 生產者 imp…

邀請函|澎峰科技邀您參加CCF HPC China2023

一年一度的全球超算盛會&#xff01; 以“算力互聯智領未來”為主題的第十九屆全國高性能計算學術年會&#xff08;CCF HPC China 2023&#xff09;將于8月24-26日&#xff08;展覽23-25日&#xff09;在青島紅島國際會議展覽中心舉辦。 九大院士領銜 打造頂級超算盛會 力邀…

《離散數學及其應用(原書第8版)》ISBN978-7-111-63687-8 第11章 11.1.3 樹的性質 節 第664頁的例9說明

《離散數學及其應用&#xff08;原書第8版&#xff09;》ISBN978-7-111-63687-8 第11章 11.1.3 樹的性質 節 第664頁的定理3的引申 定理3 帶有i個內點的m叉樹含有nmi1個頂點 見本人博文 內點定義不同的討論 如果對于一個m叉正則樹&#xff0c;即任意分支節點的兒子恰好有m個&am…

談談IP地址和子網掩碼的概念及應用

個人主頁&#xff1a;insist--個人主頁?????? 本文專欄&#xff1a;網絡基礎——帶你走進網絡世界 本專欄會持續更新網絡基礎知識&#xff0c;希望大家多多支持&#xff0c;讓我們一起探索這個神奇而廣闊的網絡世界。 目錄 一、IP地址的概念 二、IP地址的分類 1、A類 …

長勝證券:散戶可以隨大流嗎?怎么做才好?

在我國的股市里邊&#xff0c;最不缺的或許便是散戶了&#xff0c;一方面&#xff0c;散戶促進了股市的活潑&#xff0c;可一方面又特容易望風而動&#xff0c;追漲殺跌。因此&#xff0c;散戶能夠隨大流嗎&#xff1f;該怎么做才好&#xff1f;對于這些&#xff0c;長勝證券為…

IntelliJ IDEA熱部署:JRebel插件的安裝與使用

熱部署 概述JRebel 概述 熱部署&#xff0c;指修改代碼后&#xff0c;無需停止應用程序&#xff0c;即可使修改后的代碼生效&#xff0c;其有利于提高開發效率。 熱部署方式&#xff1a; 手動熱部署&#xff1a;修改代碼后&#xff0c;重新編譯項目&#xff0c;然后啟動應用程…

Springboot項目啟動后按順序加載自定義類 (demo)

1. 實現ApplicationRunner接口, 重寫run方法 import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.annotation.Order; import org.springframewor…

IDEA啟動報錯java.nio.charset.MalformedInputException: Input length=2

IDEA啟動報錯java.nio.charset.MalformedInputException: Input length2 問題解決后記 問題 原本系統運行好好得&#xff0c;一段時間沒打開&#xff0c;再次打開重啟 IDEA啟動報錯java.nio.charset.MalformedInputException: Input length2。 解決 百度了 https://blog.csd…

使用 Qt 生成 Word 和 PDF 文檔的詳細教程

系列文章目錄 文章目錄 系列文章目錄前言一、安裝 Qt二、生成 Word 文檔三、生成 PDF 文檔四、運行代碼并查看結果五、自定義文檔內容總結前言 Qt 是一個跨平臺的應用程序開發框架,除了用于創建圖形界面應用程序外,還可以用來生成 Word 和 PDF 文檔。本文將介紹如何使用 Qt …

【C語言】const修飾普通變量和指針

大家好&#xff0c;我是蘇貝&#xff0c;本篇博客帶大家了解const修飾普通變量和指針&#xff0c;如果你覺得我寫的還不錯的話&#xff0c;可以給我一個贊&#x1f44d;嗎&#xff0c;感謝?? 文章目錄 一.const修飾普通變量二.const修飾指針1.const 放在 * 左邊2.const 放在…

git commit用法

git commit 是 Git 版本控制系統中的一個命令&#xff0c;用于將更改提交到本地存儲庫。以下是 git commit 的一些常見用法和選項&#xff1a; 基本用法: git commit -m "提交信息"使用 -m 選項可以直接在命令行中添加提交信息。 提交所有更改: git commit -a -m &q…

設計模式-簡單工廠模式

簡單工廠模式又稱為靜態工廠模式&#xff0c;其實就是根據傳入參數創建對應具體類的實例并返回實例對象&#xff0c;這些類通常繼承至同一個父類&#xff0c;該模式專門定義了一個類來負責創建其他類的實例。 using System.Collections; using System.Collections.Generic; us…

Nacos - 安裝指南(Windows系統)

一、下載安裝包 Nacos現在雖然已經出到二點幾的版本&#xff0c;但二點幾版本還處在測試階段&#xff0c;我們選擇下載成熟的 1.4.6 版本 下載地址&#xff1a;Nacos 1.4.6 GitHub的Release下載頁 拉到頁面最底部&#xff0c;可以看到下載按鈕&#xff0c;windows版本使用naco…

htmlCSS-----彈性布局

目錄 前言 什么是彈性布局 樣式 學習概要 容器和項目 彈性布局的排列方式 1.橫向排列&#xff08;默認樣式&#xff09; 2.父元素容器的屬性&#xff08;*5&#xff09; &#xff08;1&#xff09;主軸 代碼示例&#xff1a; &#xff08;2&#xff09;交叉軸 3.子元素…

正則表達式試煉

序 我希望在這里列出我很多想寫的正則表達式&#xff0c;很多我想寫&#xff0c;但是不知道怎么寫的。分享點滴案例。未來這個文章會越來越長 前言 互聯網時代&#xff0c;除了文本還有更好的學習方式&#xff0c;下面是幾個不錯的練習網站&#xff0c;如果你想系統地學習&a…

[Flutter]有的時候調用setState(() {})報錯?

先看FlutterSDK的原生類State中有一個變量mounted。 abstract class State<T extends StatefulWidget> with Diagnosticable {/// mounted的作用是&#xff0c;此State對象當前是否在樹中。/// 在創建State對象之后&#xff0c;在調用initState之前&#xff0c;框架通過…

【Linux】【驅動】應用層和驅動層傳輸數據

【Linux】【驅動】應用層和驅動層傳輸數據 緒論1.如果我在應用層使用系統0 對設備節點進行打開&#xff0c;關閉&#xff0c;讀寫等操作會發生什么呢? 2 我們的應用層和內核層是不能直接進行數據傳輸的3 驅動部分的代碼4 應用代碼5 編譯以及運行代碼 緒論 Linux一切皆文件! 文…

如何使用CSS實現一個下拉菜單?

聚沙成塔每天進步一點點 ? 專欄簡介? 使用CSS實現下拉菜單? HTML 結構? CSS 樣式? 寫在最后 ? 專欄簡介 前端入門之旅&#xff1a;探索Web開發的奇妙世界 記得點擊上方或者右側鏈接訂閱本專欄哦 幾何帶你啟航前端之旅 歡迎來到前端入門之旅&#xff01;這個專欄是為那些…

學習筆記」左偏樹

dist 的性質 對于一棵二叉樹&#xff0c;我們定義左孩子或右孩子為空的節點為外節點&#xff0c;定義外節點的 distdist 為 11&#xff0c;空節點的 distdist 為 00&#xff0c;不是外節點也不是空節點的 distdist 為其到子樹中最近的外節點的距離加一。 一棵根的 distdist 為…