C++双冒号和单冒号的用法区别
生活随笔
收集整理的這篇文章主要介紹了
C++双冒号和单冒号的用法区别
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一.單冒號(:)
1.用作位域標號
? ? 有些信息在存儲時,并不需要占用一個完整的字節, 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省存儲空間,并使處理簡便,C語言又提供了一種數據結構,稱為“位域”或“位段”。所謂“位域”是把一個字節中的二進位劃分為幾個不同的區域,并說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。這樣就可以把幾個不同的對象用一個字節的二進制位域來表示。 一、位域的定義和位域變量的說明位域定義與結構定義相仿,其形式為:?
? ? struct 位域結構名?
? ? { 位域列表 };?
其中位域列表的形式為:?類型說明符?位域名:位域長度?
例如:?
[cpp]?view plaincopy print? struct?bs??? {??? ??int?a:8;??? ??int?b:2;??? ??int?c:6;??? };??? 位域變量的說明與結構變量說明的方式相同。 可采用先定義后說明,同時定義說明或者直接說明這三種方式。例如:?
[cpp]?view plaincopy print? struct?bs??? {??? ??int?a:8;??? ??int?b:2;??? ??int?c:6;??? }data;??? 說明data為bs變量,共占兩個字節。其中位域a占8位,位域b占2位,位域c占6位。對于位域的定義尚有以下幾點說明:?
1. 一個位域必須存儲在同一個字節中,不能跨兩個字節。如一個字節所剩空間不夠存放另一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。例如:?
[cpp]?view plaincopy print? struct?bs??? {??? ??unsigned?a:4??? ??unsigned?:0?/*空域*/??? ??unsigned?b:4?/*從下一單元開始存放*/??? ??unsigned?c:4??? }??? 在這個位域定義中,a占第一字節的4位,后4位填0表示不使用,b從第二字節開始,占用4位,c占用4位。?
2. 位域可以無位域名,這時它只用來作填充或調整位置。無名的位域是不能使用的。例如:?
[cpp]?view plaincopy print? struct?k??? {??? ??int?a:1??? ??int?:2?/*該2位不能使用*/??? ??int?b:3??? ??int?c:2??? };???
[cpp]?view plaincopy print? int?a,b,c;?? a=3;?? b=2;?? c=a>b?a:b;//?如果a>b成立,則反a賦給c,否則把b賦給c?? 條件語句的結構為:
條件表達式?表達式1:表達式2
當條件表達式為true時,表達式的值為表達式1的值,否則為表達式2的值。
幾點說明:
1)可以嵌套,但不推薦使用(難懂),下面的表達式你能看懂啥意思不?
[cpp]?view plaincopy print? int?max?=?i>j???i>k???i?:?k?:?j>k???j?:?k;?? 腦袋大了吧,呵呵。
2)具有很低的優先級,這個要注意哦,下面的程序執行結果是啥呢?
[cpp]?view plaincopy print? int?i?=?3;?? int?j?=?2;?? cout?<<?i>j?i:j;//?出錯,<span?style="font-family:?Arial;?font-size:?15.5555562973022px;?line-height:?26px;?color:?rgb(0,?147,?0);"><strong><<比>具有更高的優先級</strong></span><span?style="font-family:?Arial;?font-size:?15.5555562973022px;?line-height:?26px;">,執行順序為?((cout<<i)>j)?i:j,相當于是比較cout<<i與j的大小,然后根據比較結果決定表達式值為i或j,這顯然要出錯的,cout<<i的值是cout,不能跟整型數j進行比較。</span><br?style="font-family:?Arial;?font-size:?15.5555562973022px;?line-height:?26px;"?/><span?style="font-family:?Arial;?font-size:?15.5555562973022px;?line-height:?26px;">cout?<<?(i>j)?i:j;//輸出1或0,相當于(cout<<(i>j))作為判決條件,來決定表達式的值為i或j,而cout<<(i>j),i>j則輸出1否則0,然后再將(cout<<(i>j))作為?:的條件,如果cout正確執行則為1(true),否則為0(false),以此決定表達式值為i或j</span><br?style="font-family:?Arial;?font-size:?15.5555562973022px;?line-height:?26px;"?/><span?style="font-family:?Arial;?font-size:?15.5555562973022px;?line-height:?26px;">cout?<<(i>j?i:j);//i>j則輸出i,否則輸出j,表達式值為true如果cout正確執行,否則為false</span>??
更多的關于優先級的問題就不說了。 3.用作語句標簽
通常跟goto配合使用,如:
[cpp]?view plaincopy print? step1:?a?=?f1();?? ???????....?? ???????goto?step1;?? 這種作法也不是很推薦,原因在于它破壞了語句的順序執行,這樣的代價大家應該清楚吧。不過存在即為合理嘛,既然它還存在,肯定還是有它的用處有它的好處的,比如說,多層嵌套的退出(會比break continue直觀一點吧),也可以避免重復代碼之類之類的
4.用作初始化列表
在構造函數后面緊跟著冒號加初始化列表,各初始化變量之間以逗號(,)隔開。下面舉個例子。
[cpp]?view plaincopy print? class?myClass?? {?? public?:?? ??myClass();//?構造函數,無返回類型,可以有參數列表,這里省去?? ??~myClass();//?析構函數?? ??int?a;?? ??const?int?b;?? }?? myClass::myClass():a(1),b(1)//?初始化列表?? {?? }?? 5.聲明基類
假設我們重新定義一個類,繼承自myClass類。定義方式如下:
[cpp]?view plaincopy print? class?derivedClass?:?public?myClass?? {?? //?略去?? }?? ? ? ? ? 這里的冒號起到的就是聲名基類的作用,在基類類名前面可以加public\private\protected等標簽,用于標識繼承的類型,也可以省略,省略的話,用class定義的類默認為private,用struct定義的類默認為public。 與初始化列表一樣的,這里也可以聲名多個基類,各基類之間用逗號(,)隔開。
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) ::是作用域,說明CAboutDlg是類內部的一個函數 :是初始化,由于CAboutDialog類從CDialog繼承過來的,所以需要對其父類進行初始化 原型應該是這樣的 class CDialog { CDialog(UINT IDD); } class CAboutDlg : public CDialg { public: CAboutDlg() } CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
這個是CAboutDlg的構造函數,由于CAboutDlg在構造時需要構造CDialog(沒有父親就沒有兒子),所以在構造CAboutDlg時需要初始化CDialog類, 由于構造函數CAboutDlg寫在類外面,所以需要::來說明作用域是CAboutDlg類,而構造函數后面接初始化則需要用:,如果你的CAboutDlg類中還有成員變量比如 int i之類的,還可以接在后面繼續來初始化如:CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD),i(10) :表示初始化開始,如果多個成員初始化用,隔開。 二.雙冒號(::)用法
1.表示“域操作符”
例:聲明了一個類A,類A里聲明了一個成員函數void f(),但沒有在類的聲明里給出f的定義,那么在類外定義f時,?
就要寫成void A::f(),表示這個f()函數是類A的成員函數。
2.直接用在全局函數前,表示是全局函數?
例:在VC里,你可以在調用API 函數里,在API函數名前加::
3.表示引用成員函數及變量,作用域成員運算符
例:System::Math::Sqrt()?相當于System.Math.Sqrt()
4.命名空間作用域符,即2直接用在全局函數前,表示是全局函數?
在運算符等級中屬于最高級的!
using namespace 命名空間名(如,abc);
表示在以下程序代碼中所使用的標示符(如果此標示符在abc中定義)是abc中的,包括類型名(類),變量名,函數名,對象名。。。
using abc::標示符(i);
只表示在以下代碼中使用的標示符i是abc中的。
如果你要使用abc中的多個標示符的話,你就只能用
[cpp]?view plaincopy print? using?abc::a;?? using?abc::b;?? using?abc::c;?? ...?? 等一個一個列舉出來!
當然用using 語句是比較方便的
但是不安全
(1)using namespace;萬一不同的兩個命名空間中使用了同名的標示符,系統則不能判斷,這個標示符是屬于哪個命名空間的;
(2)using abc::;萬一你的程序中也用到了一個函數(函數名與abc中的這個函數同名),那么系統也不能判斷你使用的是abc中的那個函數,還是本程序中的那個函數;
最安全的辦法(當然也是最繁瑣的)
就是,每當你用到一個變量(函數...)時,你都要明確他的來歷(即屬于哪個命名空間)除非它沒有命名空間
例如:
[cpp]?view plaincopy print? #include?<iostream>?? int?main?()?? {?? std::cout?<<?"hello,?world!"?<<?std::endl;?? }?? 這里就用到了iostream文件中的兩個對象(cout,endl)
因為C++標準庫中絕大部分的函數,對象...都放在了命名空間std中
所以
上面的代碼就等同于
[cpp]?view plaincopy print? #include?<iostream>?? using?std::cout;?? using?std::endl;?? int?main?()?? {?? cout?<<?"hello,?world!"?<<?endl;?? }?? ?? #include?<iostream>?? using?namespace?std;?? int?main?()?? {?? cout?<<?"hello,?world!"?<<?endl;?? }??
重新舉個例子,再加以說明:
[cpp]?view plaincopy print? #include?<iostream>?? #include?<string>?? int?main?()?? {?? int?a;?? std::string?b;?? std::cin?>>?a;?? std::cin?>>?b;?? std::cout?<<?"hello,?world!"?<<?std::endl;?? return?0;?? }??
1)using std::; [cpp]?view plaincopy print? #include?<iostream>?? #include?<string>?? using?std::cin;?? using?std::endl;?? using?std::string;?? int?main?()?? {?? ????int?a;?? ????string?b;?? ????cin?>>?a;?? ????cin?>>?b;?? ????std::cout?<<?"hello,?world!"?<<?endl;?//注意cout沒用用using?? ????return?0;?? }??
2)using namespace ;
[cpp]?view plaincopy print? #include?<iostream>?? #include?<string>?? using?namespace?std;?? int?main?()?? {?? ????int?a;?? ????string?b;?? ????cin?>>?a;?? ????cin?>>?b;?? ????cout?<<?"hello,?world!"?<<?endl;?? ????return?0;?? }??
其中cout endl cin string都是std中的!
? ? 有些信息在存儲時,并不需要占用一個完整的字節, 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省存儲空間,并使處理簡便,C語言又提供了一種數據結構,稱為“位域”或“位段”。所謂“位域”是把一個字節中的二進位劃分為幾個不同的區域,并說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。這樣就可以把幾個不同的對象用一個字節的二進制位域來表示。 一、位域的定義和位域變量的說明位域定義與結構定義相仿,其形式為:?
? ? struct 位域結構名?
? ? { 位域列表 };?
其中位域列表的形式為:?類型說明符?位域名:位域長度?
例如:?
[cpp]?view plaincopy print?
[cpp]?view plaincopy print?
1. 一個位域必須存儲在同一個字節中,不能跨兩個字節。如一個字節所剩空間不夠存放另一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。例如:?
[cpp]?view plaincopy print?
2. 位域可以無位域名,這時它只用來作填充或調整位置。無名的位域是不能使用的。例如:?
[cpp]?view plaincopy print?
3. 取地址操作符&不能應用在位域字段上;
4. 位域字段不能是類的靜態成員;
5.?位域字段在內存中的位置是按照從低位向高位的順序放置的;
6.?當要把某個成員說明成位域時,其類型只能是int,unsigned int與signed int三者之一(說明:int類型通常代表特定機器中整數的自然長度。short類型通常為16位,long類型通常為32位,int類型可以為16位或32位.各編譯器可以根據硬件特性自主選擇合適的類型長度.見The C Programming Language中文 P32)。
另:C++標準庫提供了一個bitset 類模板,它可以輔助操縱位的集合。在可能的情況下應盡可能使用它來取代位域。
從以上分析可以看出,位域在本質上就是一種結構類型, 不過其成員是按二進位分配的。
[cpp]?view plaincopy print?
條件表達式?表達式1:表達式2
當條件表達式為true時,表達式的值為表達式1的值,否則為表達式2的值。
幾點說明:
1)可以嵌套,但不推薦使用(難懂),下面的表達式你能看懂啥意思不?
[cpp]?view plaincopy print?
2)具有很低的優先級,這個要注意哦,下面的程序執行結果是啥呢?
[cpp]?view plaincopy print?
更多的關于優先級的問題就不說了。 3.用作語句標簽
通常跟goto配合使用,如:
[cpp]?view plaincopy print?
4.用作初始化列表
在構造函數后面緊跟著冒號加初始化列表,各初始化變量之間以逗號(,)隔開。下面舉個例子。
[cpp]?view plaincopy print?
假設我們重新定義一個類,繼承自myClass類。定義方式如下:
[cpp]?view plaincopy print?
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) ::是作用域,說明CAboutDlg是類內部的一個函數 :是初始化,由于CAboutDialog類從CDialog繼承過來的,所以需要對其父類進行初始化 原型應該是這樣的 class CDialog { CDialog(UINT IDD); } class CAboutDlg : public CDialg { public: CAboutDlg() } CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
這個是CAboutDlg的構造函數,由于CAboutDlg在構造時需要構造CDialog(沒有父親就沒有兒子),所以在構造CAboutDlg時需要初始化CDialog類, 由于構造函數CAboutDlg寫在類外面,所以需要::來說明作用域是CAboutDlg類,而構造函數后面接初始化則需要用:,如果你的CAboutDlg類中還有成員變量比如 int i之類的,還可以接在后面繼續來初始化如:CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD),i(10) :表示初始化開始,如果多個成員初始化用,隔開。 二.雙冒號(::)用法
1.表示“域操作符”
例:聲明了一個類A,類A里聲明了一個成員函數void f(),但沒有在類的聲明里給出f的定義,那么在類外定義f時,?
就要寫成void A::f(),表示這個f()函數是類A的成員函數。
2.直接用在全局函數前,表示是全局函數?
例:在VC里,你可以在調用API 函數里,在API函數名前加::
3.表示引用成員函數及變量,作用域成員運算符
例:System::Math::Sqrt()?相當于System.Math.Sqrt()
4.命名空間作用域符,即2直接用在全局函數前,表示是全局函數?
在運算符等級中屬于最高級的!
using namespace 命名空間名(如,abc);
表示在以下程序代碼中所使用的標示符(如果此標示符在abc中定義)是abc中的,包括類型名(類),變量名,函數名,對象名。。。
using abc::標示符(i);
只表示在以下代碼中使用的標示符i是abc中的。
如果你要使用abc中的多個標示符的話,你就只能用
[cpp]?view plaincopy print?
當然用using 語句是比較方便的
但是不安全
(1)using namespace;萬一不同的兩個命名空間中使用了同名的標示符,系統則不能判斷,這個標示符是屬于哪個命名空間的;
(2)using abc::;萬一你的程序中也用到了一個函數(函數名與abc中的這個函數同名),那么系統也不能判斷你使用的是abc中的那個函數,還是本程序中的那個函數;
最安全的辦法(當然也是最繁瑣的)
就是,每當你用到一個變量(函數...)時,你都要明確他的來歷(即屬于哪個命名空間)除非它沒有命名空間
例如:
[cpp]?view plaincopy print?
因為C++標準庫中絕大部分的函數,對象...都放在了命名空間std中
所以
上面的代碼就等同于
[cpp]?view plaincopy print?
重新舉個例子,再加以說明:
[cpp]?view plaincopy print?
1)using std::; [cpp]?view plaincopy print?
2)using namespace ;
[cpp]?view plaincopy print?
其中cout endl cin string都是std中的!
總結
以上是生活随笔為你收集整理的C++双冒号和单冒号的用法区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯手机管家pc版怎么一键root(一键
- 下一篇: 口袋妖怪复刻巨钳天蝎怎么配招