【C++】用命名空間避免命名沖突

  • 🌸博主主頁:@釉色清風
  • 🌸文章專欄:C++
  • 🌸今日語錄:如果神明還不幫你,說明他相信你。
  • 🪷文章簡介:這篇文章是結合譚浩強老師的書以及自己的理解,同時加入了一些例子,方便理解。希望對大家有幫助。

用命名空間避免命名沖突

  • 🌼名字沖突問題
    • 🌻例子
    • 🌻名字沖突
  • 🌼命名空間
    • 🌻命名空間的類型
    • 🌻命名空間的成員
    • 🌻命名空間的使用
  • 🌼使用命名空間解決名字沖突

🌼名字沖突問題

在實際生活中,一個大型的項目往往不是一個人獨立完成的,而是由若干個人合作完成的,不同的人分別完成不同的部分,最后組合成一個完整的程序。

假如不同的人分別定義了類,放在不同的頭文件中,在主文件(包含主函數的文件)需要用這些類時,就用#include指令將這些頭文件包含進來。

由于各頭文件是由不同的人設計的,有可能在不同的頭文件中用了相同的名字來命名所定義的類或函數。這樣在程序中就會出現名字沖突

🌻例子

程序員甲在頭文件header1.h中定義了類Student和函數fun:

#pragma once
//header1.h
#include <iostream>
#include<string>
#include <cmath>
using namespace std;
class Student //聲明Student類
{
public:Student(int n, string nam, int a){num = n;name = nam;age = a;}void get_data();
private:int num;string name;int age;
};
//成員函數的定義
void  Student::get_data()
{cout<< num <<"" << name << "" << age << endl;
}
//定義全局函數(即外部函數)
double fun(double a, double b)
{return sqrt(a + b);
}

在main函數所在的主文件中包含文件header1.h:

#include "header1.h"
int main()
{Student stud1(101,"Wang",18);stud1.get_data;cout<<fun(5,3)<<endl;return 0;
}

運行結果如下:

如果程序員乙寫了頭文件head2.h,在其中定義了其他類以外,還定義了類Student和函數fun,但其內容與頭文件header1.h中的Student和函數fun有所不同。

//header2.h
#pragma once
#include <string.h>
#include<cmath>
#include<iostream>
using namespace std;
class Student
{
public:Student(int n, string nam, char s)//參數與header1.h中不同{num = n;name = nam;sex = s;}void get_data();
private:int num;string name;char sex;
};//成員函數定義
void Student::get_data()
{cout << num << "" << name << "" << sex << endl;
}
//定義全局函數
double fun(double a, double b)
{return sqrt(a - b);//返回值與header1中的fun函數不同
}
......
//頭文件2可能還有其他的內容

假如主程序員在其程序中要用到header1.h中的Student和函數fun,因而在程序中包含了頭文件header1.h,同時又要用到頭文件header2.h中的一些內容,但是不知道此時header2.h中包含了與header1.h同名單內容不同的Student類和fun函數,因而又在頭文件中包含了頭文件header2.h。

主文件如下:

//main file
#include <iostream>
#include "header1.h"
#include "header2.h"int main()
{Student stud1(101,"Wang",18);stud1.get_data;cout<<fun(5,3)<<endl;return 0;
}

這時,程序編譯就會出現錯誤。

🌻名字沖突

因為在預編譯后,頭文件中的內容取代了對應的#include指令,這樣就在同一個程序文件中出現了兩個Student類和兩個fun函數,顯然是重復定義,這就是名字沖突。
名字沖突,即在同一個作用域中含有兩個或多個同名的實體。
不僅如此,在程序中往往還需要引用一些庫,包括C++編譯系統提供的庫、由軟件開發商提供的庫或者用戶自己開發的庫,為此需要包含有關的頭文件。如果在這些庫中包含有與程序的全局實體同名的實體,或者不同的庫中有相同的實體名,則在編譯時就會出現名字沖突。有人稱之為全局命名空間污染

為了避免這類問題的出現,人們提出了許多方法,例如:將實體的名字寫得長一點(包含十幾個或幾十個字母和字符);把名字搞得特殊一些,包括一些特殊的字符;由編譯系統提供的內部全局標識符都用下劃線作為前綴,如_complex(),以避免與用戶的實體同名;由軟件開發商提供的尸體的名字用特定的字符作為前綴等。但是這樣的效果并不理想,而且增加了閱讀程序的難度,即可讀性降低了。

C語言和早期的C++語言沒有提供有效的機制來解決這個問題,沒有庫的提供者能夠建立自己的命名空間。人們希望ANSI C++ 標準庫能夠解決這個問題,提供一種機制、一種工具,使由庫的設計者命名的全局標識符能夠和程序的全局實體名以及其他類的全局標識符區別開來。

🌼命名空間

為了解決這個問題,ANSI C++增加了命名空間。
所謂命命名空間,就是一個由程序設計者命名的內存區域。程序設計者可以根據需要指定一些有名字的空間域,把一些全局實體分別放在各個命名空間中,從而與其他全局實體分離開來。
我的理解就是原來我們的全局實體變量都是“暴露出來”的,然后命名空間的作用就是分別個你需要的全局實體“圍起來”,像柵欄一樣,每一塊區域都有一個專屬于自己的名字。然后在編譯階段,就像是好多個“圍起來的柵欄”,且各不相同。

命名空間的作用是建立一些互相分隔的作用域,把一些全局實體分隔開來,以免產生名字沖突。

這里有一段很形象的描述,可以幫助大家更好地理解:
例如,某中學高三年級有3個叫李相國的學生,如果都在同一班,那么老師點名叫李相國時,3個人都站起來應答,這就是名字沖突。因為他們無法辨別老師想叫的是哪一個李相國?同名者無法互相區分。為了避免同名混淆,學校把3個同名的學生分在3個班。這樣,在小班點名叫李相國時,只會有一個人應答。也就是說,在該班的范圍內,即班作用域內名字是唯一的。如果在全校集合時校長點名,需要在全校范圍內找這個學生,要考慮的作用域是全校范圍。如果校長叫李相國,全校學生中又會有3個人一齊喊“到”,因為在同一作用域中存在3個同名學生。為了在全校范圍內區分這3名學生,即加上班名限定。這樣就不會產生混淆。

可以根據需要設置許多個命名空間,每個命名空間代表一個不同的命名空間域,不同的命名空間不能同名。這樣,可以把不同的庫中的實體放到不同的命名空間中,或者說,用不同的命名空間把不同的實體隱藏起來。過去用的全局變量可以理解為存在于全局命名空間,獨立域所有有名的命名空間之外,不是不需要namespace聲明的,實際上是由系統隱式聲明的,在該空間中有效。

🌻命名空間的類型

在聲明一個命名空間時,花括號內不僅可以包括變量,而且還可以包括一下類型:

  • 變量(可以帶有初始化);
  • 常量;
  • 函數(可以是定義或聲明);
  • 結構體;
  • 類;
  • 模板;
  • 命名空間(在一個命名空間中又定義了一個命名空間,即嵌套的命名空間)。

🌻命名空間的成員

例如:

namespace ns1 //指定命名空間ns1
{int a;double b;
}
  • ns1是命名空間的名字。
  • 在花括號內,聲明的實體即為命名空間的成員,包括全局變量a和b。
  • 使用a和b,需要加上命名空間和作用域分辨符"::",如ns1::a,ns1::b。
  • 需要注意的是,a和b仍然是全局變量,僅僅是把他們放在了命名空間中而已。

🌻命名空間的使用

舉例如下:

namespace ns1
{const int RATE=0.08;//常量double pay;//變量double tax()//函數{return a*RATE;}namespace ns2 //嵌套命名空間int age;}

輸出命名空間中ns1中成員的數據:

cout<<ns1::RATE<<endl;
cout<<ns1::pay<<endl;
cout<<ns1::tax()<<end;
cout<<ns1::ns2::age<<endl;

🌼使用命名空間解決名字沖突

聲明命名空間ns1,并在命名空間ns1中聲明Student類和定義成員函數、定義fun函數。

#pragma once
//header1.h
#include <iostream>
#include<string>
#include <cmath>
using namespace std;
namespace ns1 {class Student //聲明Student類{public:Student(int n, string nam, int a){num = n;name = nam;age = a;}void get_data();private:int num;string name;int age;};//成員函數的定義void  Student::get_data(){cout << num << "" << name << "" << age << endl;}//定義全局函數(即外部函數)double fun(double a, double b){return sqrt(a + b);}
}

在header2.h中,聲明命名空間ns2,并在命名空間ns2中定義Student類和 成員函數以及fun函數。

using namespace std;
namespace ns2
{class Student{public:Student(int n, string nam, char s)//參數與header1.h中不同{num = n;name = nam;sex = s;}void get_data();private:int num;string name;char sex;};//成員函數定義void Student::get_data(){cout << num << "" << name << "" << sex << endl;}//定義全局函數double fun(double a, double b){return sqrt(a - b);//返回值與header1中的fun函數不同}
}

主函數如下:

#include "header1.h";
#include "header2.h";
int main()
{ns1::Student stud1(101, "Wang", 18);//用命名空間ns1中的Student類定義stud1stud1.get_data();cout <<ns1:: fun(5, 3) << endl;//調用命名空間ns1中的fun函數ns2::Student stud2(102, "Li", 'f');//用命名空間ns2中的Student類定義stud2stud2.get_data();cout << ns2::fun(5, 3) << endl;//調用命名空間ns2中的fun函數return 0;
}

運行結果如下:

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

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

相關文章

NOC2023軟件創意編程(學而思賽道)python小高組初賽真題

軟件創意編程 一、參賽范圍 1.參賽組別:小學低年級組(1-3 年級)、小學高年級組(4-6 年級)、初中組。 2.參賽人數:1 人。 3.指導教師:1 人(可空缺)。 4.每人限參加 1 個賽項。 組別確定:以地方教育行政主管部門(教委、教育廳、教育局) 認定的選手所屬學段為準。 二、…

MATLAB知識點:if條件判斷語句的嵌套

?講解視頻&#xff1a;可以在bilibili搜索《MATLAB教程新手入門篇——數學建模清風主講》。? MATLAB教程新手入門篇&#xff08;數學建模清風主講&#xff0c;適合零基礎同學觀看&#xff09;_嗶哩嗶哩_bilibili 節選自?第4章&#xff1a;MATLAB程序流程控制 我們通過一個…

基于springboot+vue的教師工作量管理系統

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

Java集合-Map接口

在Java中&#xff0c;Map接口表示鍵值對的集合&#xff0c;其中每個鍵都是唯一的&#xff0c;并且每個鍵映射到一個值。Map接口是集合框架中的一部分&#xff0c;位于java.util包中。它定義了一系列操作來管理鍵值對&#xff0c;例如添加鍵值對、刪除鍵值對、獲取鍵對應的值等。…

7.1.1 selenium介紹及安裝chromedriver

目錄 1. Selenium的用途 2. 安裝Selenium庫 3. 安裝chromedriver 1. 查看谷歌版本號?編輯 2. 找到最新版本及下載 3. 配置環境變量 4. 檢測是否配置成功 5. 用python初始化瀏覽器對象檢測&#xff1a; 6. 參考鏈接 1. Selenium的用途 在前面我們提到&#xff1a;在我…

Github項目推薦-LightMirrors

項目地址 https://github.com/NoCLin/LightMirrors 項目簡述 “LightMirrors是一個開源的緩存鏡像站服務&#xff0c;用于加速軟件包下載和鏡像拉取。目前支持DockerHub、PyPI、PyTorch、NPM等鏡像緩存服務。 當前項目仍處于早期階段。”–來自項目說明。 也就是說&#xff…

爆紅提醒:ESLint: Parsing error: Unexpected token. Did you mean `{‘>‘}` or `gt;`?

錯誤情況&#xff1a;> 會爆紅提示&#xff1a;ESLint: Parsing error: Unexpected token. Did you mean {>} or >? function().then((res) > {console.log(res.data); }解決方法&#xff1a;修改.eslintrc或者.eslintrc.js的配置 module.exports {// 其他配置..…

RocketMq——Consume相關源碼

摘要 RocketMQ只要有CommitLog文件就可以正常運行了&#xff0c;那為何還要維護ConsumeQueue文件呢&#xff1f; ConsumeQueue是消費隊列&#xff0c;引入它的目的是為了提高消費者的消費速度。畢竟RocketMQ是基于Topic主題訂閱模式的&#xff0c;消費者往往只關心自己訂閱的…

定制開發一款家政小程序,應知應會

引言 在這個快節奏的現代生活中&#xff0c;人們對高效、便捷的家政服務的需求日益增加。隨著社會結構的變化和職業生活的繁忙&#xff0c;許多家庭面臨著時間不足、精力不濟的挑戰。在這種情況下&#xff0c;家政服務成為解決問題的有效途徑。然而&#xff0c;傳統的家政服務…

Python——桌面攝像頭軟件(附源碼+打包)

目錄 一、前言 二、桌面攝像頭軟件 2.1、下載項目 2.2、功能介紹 三、打包工具&#xff08;nuitka&#xff09; 四、項目文件復制&#xff08;我全部合到一個文件里面了&#xff09; 五、結語 一、前言 看見b站的向軍大叔用electron制作了一個桌面攝像頭軟件 但是&#x…

PPT 批量刪除每頁相同位置的內容

方法&#xff1a; 選擇【視圖】&#xff0c;【宏】&#xff0c;設置宏的名稱&#xff0c;點創建將下列函數復制到宏中&#xff0c;在ppt中先選擇某個要刪除的對象&#xff0c;然后運行宏即可 函數內容如下 Sub Delete( ) Dim oSlide As Slide, oShape As Shape Dim myWidt…

如何在jupyter notebook 中下載第三方庫

在anconda 中找到&#xff1a; Anaconda Prompt 進入頁面后的樣式&#xff1a; 在黑色框中輸入&#xff1a; 下載第三方庫的命令 第三方庫&#xff1a; 三種輸入方式 標準保證正確 pip instsall 包名 -i 鏡像源地址 pip install pip 是 Python 包管理工具&#xff0c;…

新項目,Linux上一鍵安裝MySQL,Redis,Nacos,Minio

大家好&#xff0c;我是 jonssonyan 分享一個我的一個開源項目&#xff0c;這是一個在 Linux 平臺上一鍵安裝各種軟件的腳本項目&#xff0c;腳本使用 Shell 語言編寫&#xff0c;后續還會增加更多軟件的一鍵安裝&#xff0c;代碼在 GitHub 上全部開源的&#xff0c;開源地址如…

【Python】進階學習:pandas--如何根據指定條件篩選數據

【Python】進階學習&#xff1a;pandas–如何根據指定條件篩選數據 &#x1f308; 個人主頁&#xff1a;高斯小哥 &#x1f525; 高質量專欄&#xff1a;Matplotlib之旅&#xff1a;零基礎精通數據可視化、Python基礎【高質量合集】、PyTorch零基礎入門教程&#x1f448; 希望…

2024第二次培訓:win11系統下使用nginx、JDK、mysql搭建基于vue2、java前后端分離的web應用運行環境

一.背景 公司安排了帶徒弟的任務&#xff0c;給培訓寫點材料。前面分開介紹了mysql、jdk、nginx的安裝&#xff0c;都只是零星的介紹&#xff0c;只能算零散的學習。學習了有什么用呢&#xff1f;能解決什么問題&#xff1f;能完成什么工作&#xff1f; 今天我們要用之前的幾篇…

為什么要在業務系統中引入大寬表?

在高度系統化驅動的業務中&#xff0c;查看業務報表已經是一個很常見的需求了。在分工非常明確的大型企業里&#xff0c;往往有專門的數據分析團隊 BI 或者數據開發團隊&#xff0c;他們能夠勝任此類需求&#xff08;但也未必是輕松的&#xff0c;或者說高效的&#xff09;。 …

中國電子學會(CEIT)2023年05月真題C語言軟件編程等級考試二級(含解析答案)

中國電子學會(CEIT)考評中心歷屆真題(含解析答案) C語言軟件編程等級考試二級 2023年05月 編程題五道 總分:100分一、數字放大(20分) 給定一個整數序列以及放大倍數x,將序列中每個整數放大x倍后輸出。 時間限制: 1000 內存限制: 65536 輸入 包含三行:第一行為N,…

Stable Diffusion 模型分享:AAM XL (Anime Mix)(動漫截屏風格 XL)

本文收錄于《AI繪畫從入門到精通》專欄&#xff0c;專欄總目錄&#xff1a;點這里。 文章目錄 模型介紹生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下載地址 模型介紹 AAM XL (Anime Mix) 是一個動漫截屏風格的模型&#xff0c;是 AAM - AnyLoRA Anime Mix 模…

【yolov8部署實戰】VS2019環境下使用C++和OpenCV環境部署yolo項目|含詳細注釋源碼

一、前言 之前一陣子一直在做的就是怎么把yolo項目部署成c項目&#xff0c;因為項目需要嵌套進yolo模型跑算法。因為自己也是本科生小白一枚&#xff0c;基本上對這方面沒有涉獵過&#xff0c;自己一個人從網上到處搜尋資料&#xff0c;寫代碼&#xff0c;調試&#xff0c;期間…

黑馬JavaWeb開發跟學(三)Web前端開發Vue-Element

黑馬JavaWeb開發跟學三.Web前端開發Vue-Element 1 Ajax1.1 Ajax介紹1.1.1 Ajax概述1.1.2 Ajax作用1.1.3 同步異步 1.2 原生Ajax1.3 Axios1.3.1 Axios的基本使用1.3.2 Axios快速入門1.3.3 請求方法的別名1.3.4 案例 2 前后臺分離開發2.1 前后臺分離開發介紹2.2 YAPI2.2.1 YAPI介…