這篇文章主要為大家展示了“c++常量的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“c++常量的示例分析”這篇文章吧。
創(chuàng)新互聯(lián)公司專注于東乃網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供東乃營(yíng)銷型網(wǎng)站建設(shè),東乃網(wǎng)站制作、東乃網(wǎng)頁(yè)設(shè)計(jì)、東乃網(wǎng)站官網(wǎng)定制、小程序定制開(kāi)發(fā)服務(wù),打造東乃網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供東乃網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。概念
常量是存放固定且不可變值的,一旦確定初始值則在程序其它地方不可改變, 所以const對(duì)象必須初始化。常量一般使用const關(guān)鍵字來(lái)修飾。
const 對(duì)象可以大致分為三類:
1. const int a
const int a =10;
int const b =10;
這兩種格式是完全相同的。也就是說(shuō)const 與int哪個(gè)寫(xiě)前都不影響語(yǔ)義。有了這個(gè)概念后,我們來(lái)看這兩個(gè)家伙:const int * pi與int const * pi ,它們的語(yǔ)義有不同嗎?
你只要記住一點(diǎn),int 與const 哪個(gè)放前哪個(gè)放后都是一樣的,就好比const int n;與int const n;一樣。也就是說(shuō),它們是相同的。
2. const int * p
前面已經(jīng)說(shuō)了 const int * p與int const * p 是完全一樣的。
我們根據(jù)下面的例子看看它們的含義。
int a =30; int b =40; const int * p=&a; p=&b; //注意這里,p可以在任意時(shí)候重新賦值一個(gè)新內(nèi)存地址 b=80; //想想看:這里能用*pi=80;來(lái)代替嗎?當(dāng)然不能 printf( “%d”, *p ) ; //輸出是80
語(yǔ)義分析:
p的值是可以被修改的。即它可以重新指向另一個(gè)地址的,但是,不能通過(guò)*p來(lái)修改b的值。
首先const 修飾的是整個(gè)*p(注意,是*p而不是p)。所以*p(p指向的對(duì)象)是常量,是不能被賦值的(雖然p所指的b是變量,不是常量)。
其次,p前并沒(méi)有用const 修飾,所以p是指針變量,能被賦值重新指向另一內(nèi)存地址的。
你可能會(huì)疑問(wèn):那又如何用const 來(lái)修飾pi呢?其實(shí),你注意到int * const pi中const 的位置就大概可以明白了。請(qǐng)記住,通過(guò)格式看語(yǔ)義。 我們看看下面的定義。
3. int* const p
這里的const修飾的p,而不是上面的*p,我們根據(jù)下面的例子來(lái)分析:
int a=30; int b=40; int * const p=&a; //p=&b; 注意這里,p不能再這樣重新賦值了,即不能再指向另一個(gè)新地址。 b=80; //這里能用*p=80;來(lái)代替嗎?可以,這里可以通過(guò)*p修改a的值。 //請(qǐng)自行與前面一個(gè)例子比較。 printf( “%d”, *p ) ; //輸出是80 *p=100; printf( “%d”, a ) ; //輸出是100
語(yǔ)義分析:
p值是不能重新賦值修改了。它只能永遠(yuǎn)指向初始化時(shí)的內(nèi)存地址了。并且可以通過(guò)*p來(lái)修改a的值了。與前一個(gè)例子對(duì)照一下吧!看以下的兩點(diǎn)分析
1). p因?yàn)橛辛薱onst 的修飾,所以只是一個(gè)指針常量:也就是說(shuō)p值是不可修改的(即p不可以重新指向b這個(gè)變量了)。
2). 整個(gè)*p的前面沒(méi)有const 的修飾。也就是說(shuō),*p是變量而不是常量,所以我們可以通過(guò)*p來(lái)修改它所指內(nèi)存a的值。
總之一句話,這次的p是一個(gè)指向int變量類型數(shù)據(jù)的指針常量。
最后總結(jié)兩句:
1).如果const 修飾在*p前則不能改的是*p而不是指p
2).如果const 是直接寫(xiě)在p前則p不能改。
4.補(bǔ)充三種情況。
這里,我再補(bǔ)充以下三種情況。其實(shí)只要上面的語(yǔ)義搞清楚了,這三種情況也就已經(jīng)被包含了。不過(guò)作為三種具體的形式,我還是簡(jiǎn)單提一下吧!
情況一:int * pi指針指向const int n常量的情況
const int n1=40; int *pi; pi=&n1;//這樣可以嗎?不行,VC下是編譯錯(cuò)。const int 類型的n1的地址是不能賦值給指向int類型地址的指針pi的。否則pi豈不是能修改n1的值了嗎! pi=(int* ) &n1; // 這樣可以嗎?強(qiáng)制類型轉(zhuǎn)換可是C所支持的。 VC下編譯通過(guò),但是仍不能通過(guò)*pi=80來(lái)修改n1的值。去試試吧!看看具體的怎樣。
情況二:const int * pi指針指向const int n1的情況
const int n1=40; const int * pi; pi=&n1;//兩個(gè)類型相同,可以這樣賦值。n1的值無(wú)論是通過(guò)pi還是n1都不能修改的。
情況三:用const int * const pi申明的指針
int n; const int * const pi=&n; //你能想象pi能夠作什么操作嗎?pi值不能改,也不能通過(guò)pi修改n的值。因?yàn)椴还苁?nbsp; //*pi還是pi都是const的。
5. 常量引用
int a = 10; int& p1 = a;//正確 int& p2 = 2;//錯(cuò)誤,需要引用左值 const int& p3 = a;//正確 const int& p4 = 4;//正確
關(guān)于引用的初始化有兩點(diǎn)值得注意:
(1)當(dāng)初始化值是一個(gè)左值(可以取得地址)時(shí),沒(méi)有任何問(wèn)題,可以用常量引用也可以用非常量引用, 如p1,p3;
(2)當(dāng)初始化值不是一個(gè)左值時(shí),則只能對(duì)一個(gè)const T&(常量引用)賦值。如p2,p3。而且這個(gè)賦值是有一個(gè)過(guò)程的:
首先將值隱式轉(zhuǎn)換到類型T,然后將這個(gè)轉(zhuǎn)換結(jié)果存放在一個(gè)臨時(shí)對(duì)象里,最后用這個(gè)臨時(shí)對(duì)象來(lái)初始化這個(gè)引用變量。
如果是對(duì)一個(gè)常量進(jìn)行引用,則編譯器首先建立一個(gè)臨時(shí)變量,然后將該常量的值置入臨時(shí)變量中,對(duì)該引用的操作就是對(duì)該臨時(shí)變量的操作。對(duì)常量的引用可以用其它任何引用來(lái)初始化;但不能改變。
6. 常量函數(shù)、常量引用參數(shù)、常量引用返回值
例1:bool verifyObjectCorrectness(const myObj &obj); //const reference parameter
例2:void Add(const int &arg) const; //const function
例3:IStack const & GetStack() const { return _stack; } //return const reference
6.1 常量函數(shù)
1. 一個(gè)函數(shù)通過(guò)在其后面加關(guān)鍵字const,它將被聲明為常量函數(shù)
2. 在C++,只有將成員函數(shù)聲明為常量函數(shù)才有意義。帶有const作后綴的常量成員函數(shù)又被稱為視察者(inspector),沒(méi)
有const作后綴的非常量成員函數(shù)被稱為變異者(mutator)
3. 與const有關(guān)的錯(cuò)誤總是在編譯時(shí)發(fā)現(xiàn)
4. [摘]If the function is not declared const, in can not be applied to a const object, and the compiler will
give an error message. A const function can be applied to a non-const object
5. 在C++中,一個(gè)對(duì)象的所有方法都接收一個(gè)指向?qū)ο蟊旧淼碾[含的this指針;常量方法則獲取了一個(gè)隱含的常量this指針
void func_name() const;
以上說(shuō)明函數(shù)func_name()不會(huì)改變*this。當(dāng)你把this指針看成函數(shù)func_name()的一個(gè)不可見(jiàn)參數(shù)就理解了
void func_name(T *this) (no const)
void func_name(const T *this) (const)
6. 常量函數(shù)可以被任何對(duì)象調(diào)用,而非常量函數(shù)則只能被非常量對(duì)象調(diào)用,不能被常量對(duì)象調(diào)用,如:
class Fred { public: void inspect() const; // This member promises NOT to change *this void mutate(); // This member function might change *this }; void userCode(Fred& changeable, const Fred& unchangeable) { changeable.inspect(); // OK: doesn't change a changeable object changeable.mutate(); // OK: changes a changeable object unchangeable.inspect(); // OK: doesn't change an unchangeable object unchangeable.mutate(); // ERROR: attempt to change unchangeable object }
7. 在類中允許存在同名的常量函數(shù)和非常量函數(shù),編譯器根據(jù)調(diào)用該函數(shù)的對(duì)象選擇合適的函數(shù)
當(dāng)非常量對(duì)象調(diào)用該函數(shù)時(shí),先調(diào)用非常量函數(shù);
當(dāng)常量對(duì)象調(diào)用該函數(shù)時(shí),只能調(diào)用常量函數(shù);
如果在類中只有常量函數(shù)而沒(méi)有與其同名的非常量函數(shù),則非常量與常量對(duì)象都可調(diào)用該常量函數(shù);如:
#include <iostream> using namespace std; struct A { void f() const { cout<<"const function f is called"<<endl; } void f() { cout<<"non-const function f is called"<<endl; } void g() { cout<<"non-const function g is called"<<endl; } }; void main() { A a; const A& ref_a = a; a.f(); //calls void f(),輸出:non-const function f is called<br> ref_a.f();//calls void f () const, 輸出:const function f is called a.g(); //ok, normal call <br> ref_a.g(); //error, const object can not call non-const function }
8. const關(guān)鍵字不能用在構(gòu)造函數(shù)與析構(gòu)函數(shù)中。因?yàn)闃?gòu)造函數(shù)的目的是初始化域值,因此它必須更改對(duì)象,析構(gòu)函數(shù)同理
6.2 常量引用參數(shù)
本例中,一個(gè)myObj類型的對(duì)象obj通過(guò)引用傳入函數(shù)verifyObjectCorrectness。為安全起見(jiàn),使用了const關(guān)鍵字來(lái)確保函數(shù)verifyObjectCorrectness不會(huì)改變對(duì)象obj所引用的對(duì)象的狀態(tài)。此外,通過(guò)聲明參數(shù)常量,函數(shù)的使用者可以確保他們的對(duì)象 不會(huì)被改變,也不必?fù)?dān)心在調(diào)用函數(shù)時(shí)帶來(lái)副作用。以下代碼試圖對(duì)聲明為常量引用的形參進(jìn)行修改,從而不會(huì)通過(guò)編譯!
#include <iostream> using namespace std; class Test { public: void f(const int& arg); private: int value; }; void Test::f(const int& arg) { arg=10; //試圖修改arg的值,此行將引起編譯器錯(cuò)誤 //error C2166: l-value specifies const object cout<<"arg="<<arg<<endl; value=20; } void main() { int i=7; Test test; test.f(i); cout<<"i="<<i<<endl; }
6.3 常量引用返回值
如果你想從常量方法(函數(shù))中通過(guò)引用返回this對(duì)象的一個(gè)成員, 你應(yīng)該使用常量引用來(lái)返回它,即const X&
也就是說(shuō)你想通過(guò)引用返回的東西如果從邏輯上來(lái)講是this對(duì)象的一部分(與它是否在物理上嵌入在this對(duì)象中無(wú)關(guān)),那么常量方法需要通過(guò)常量引用或者通過(guò)值來(lái)返回,而不能通過(guò)非常量引用返回
class Person { public: const string& name_good() const; // Right: the caller can't change the name string& name_evil() const; // Wrong: the caller can change the name . }; void myCode(const Person& p) // You're promising not to change the Person object { p.name_evil() = "Igor"; // but you changed it anyway!! }
以上是“c++常量的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站jinyejixie.com,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
本文名稱:c++常量的示例分析-創(chuàng)新互聯(lián)
網(wǎng)站鏈接:http://jinyejixie.com/article4/dchsie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、網(wǎng)站導(dǎo)航、網(wǎng)站營(yíng)銷、商城網(wǎng)站、品牌網(wǎng)站建設(shè)、營(yíng)銷型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容