最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++常量詳解

 更新時間:2017年06月02日 23:26:27   作者:虎哥不唬  
常量是存放固定且不可變值的,一旦確定初始值則在程序其它地方不可改變, 所以const對象必須初始化。常量一般使用const關(guān)鍵字來修飾

概念

常量是存放固定且不可變值的,一旦確定初始值則在程序其它地方不可改變, 所以const對象必須初始化。常量一般使用const關(guān)鍵字來修飾。

const 對象可以大致分為三類:

1. const int a

const int a =10;
int const b =10;

 這兩種格式是完全相同的。也就是說const 與int哪個寫前都不影響語義。有了這個概念后,我們來看這兩個家伙:const int * pi與int const * pi ,它們的語義有不同嗎?

你只要記住一點,int 與const 哪個放前哪個放后都是一樣的,就好比const int n;與int const n;一樣。也就是說,它們是相同的。

2. const int * p

前面已經(jīng)說了 const int * p與int const * p 是完全一樣的。

我們根據(jù)下面的例子看看它們的含義。

int a =30; 
int b =40; 
const int * p=&a; 
p=&b;   //注意這里,p可以在任意時候重新賦值一個新內(nèi)存地址 
b=80;   //想想看:這里能用*pi=80;來代替嗎?當(dāng)然不能 
printf( “%d”, *p ) ;  //輸出是80 

語義分析:

p的值是可以被修改的。即它可以重新指向另一個地址的,但是,不能通過*p來修改b的值。

首先const  修飾的是整個*p(注意,是*p而不是p)。所以*p(p指向的對象)是常量,是不能被賦值的(雖然p所指的b是變量,不是常量)。
其次,p前并沒有用const 修飾,所以p是指針變量,能被賦值重新指向另一內(nèi)存地址的。

你可能會疑問:那又如何用const 來修飾pi呢?其實,你注意到int * const pi中const 的位置就大概可以明白了。請記住,通過格式看語義。 我們看看下面的定義。

3. int* const p

這里的const修飾的p,而不是上面的*p,我們根據(jù)下面的例子來分析:

int a=30; 
int b=40; 
int * const p=&a; 
//p=&b;   
注意這里,p不能再這樣重新賦值了,即不能再指向另一個新地址。 
b=80;   
//這里能用*p=80;來代替嗎?可以,這里可以通過*p修改a的值。 
//請自行與前面一個例子比較。 
printf( “%d”, *p ) ;  //輸出是80 

*p=100;

printf( “%d”, a ) ;  //輸出是100

語義分析: 
    
p值是不能重新賦值修改了。它只能永遠指向初始化時的內(nèi)存地址了。并且可以通過*p來修改a的值了。與前一個例子對照一下吧!看以下的兩點分析

     1). p因為有了const 的修飾,所以只是一個指針常量:也就是說p值是不可修改的(即p不可以重新指向b這個變量了)。

     2). 整個*p的前面沒有const 的修飾。也就是說,*p是變量而不是常量,所以我們可以通過*p來修改它所指內(nèi)存a的值。

     總之一句話,這次的p是一個指向int變量類型數(shù)據(jù)的指針常量。
最后總結(jié)兩句:
     1).如果const 修飾在*p前則不能改的是*p而不是指p
     2).如果const 是直接寫在p前則p不能改。

4.補充三種情況。

 這里,我再補充以下三種情況。其實只要上面的語義搞清楚了,這三種情況也就已經(jīng)被包含了。不過作為三種具體的形式,我還是簡單提一下吧!

情況一:int * pi指針指向const int n常量的情況

const int n1=40; 
int *pi; 
pi=&n1;//這樣可以嗎?不行,VC下是編譯錯。const int 類型的n1的地址是不能賦值給指向int類型地址的指針pi的。否則pi豈不是能修改n1的值了嗎!  
pi=(int* ) &n1;  // 這樣可以嗎?強制類型轉(zhuǎn)換可是C所支持的。 VC下編譯通過,但是仍不能通過*pi=80來修改n1的值。去試試吧!看看具體的怎樣。

情況二:const int * pi指針指向const int n1的情況

const int n1=40; 
const int * pi; 
pi=&n1;//兩個類型相同,可以這樣賦值。n1的值無論是通過pi還是n1都不能修改的。

情況三:用const int * const pi申明的指針

int n; 
const int * const pi=&n; 
//你能想象pi能夠作什么操作嗎?pi值不能改,也不能通過pi修改n的值。因為不管是 
//*pi還是pi都是const的。

5. 常量引用

int a = 10;
int& p1 = a;//正確
int& p2 = 2;//錯誤,需要引用左值
const int& p3 = a;//正確
const int& p4 = 4;//正確

關(guān)于引用的初始化有兩點值得注意:

(1)當(dāng)初始化值是一個左值(可以取得地址)時,沒有任何問題,可以用常量引用也可以用非常量引用, 如p1,p3;
(2)當(dāng)初始化值不是一個左值時,則只能對一個const T&(常量引用)賦值。如p2,p3。而且這個賦值是有一個過程的:

首先將值隱式轉(zhuǎn)換到類型T,然后將這個轉(zhuǎn)換結(jié)果存放在一個臨時對象里,最后用這個臨時對象來初始化這個引用變量。

如果是對一個常量進行引用,則編譯器首先建立一個臨時變量,然后將該常量的值置入臨時變量中,對該引用的操作就是對該臨時變量的操作。對常量的引用可以用其它任何引用來初始化;但不能改變。

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. 一個函數(shù)通過在其后面加關(guān)鍵字const,它將被聲明為常量函數(shù)
  2. 在C++,只有將成員函數(shù)聲明為常量函數(shù)才有意義。帶有const作后綴的常量成員函數(shù)又被稱為視察者(inspector),沒
         有const作后綴的非常量成員函數(shù)被稱為變異者(mutator)
  3. 與const有關(guān)的錯誤總是在編譯時發(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++中,一個對象的所有方法都接收一個指向?qū)ο蟊旧淼碾[含的this指針;常量方法則獲取了一個隱含的常量this指針
      void func_name() const;
      以上說明函數(shù)func_name()不會改變*this。當(dāng)你把this指針看成函數(shù)func_name()的一個不可見參數(shù)就理解了
      void func_name(T *this) (no const)
      void func_name(const T *this) (const)
  6. 常量函數(shù)可以被任何對象調(diào)用,而非常量函數(shù)則只能被非常量對象調(diào)用,不能被常量對象調(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ù)的對象選擇合適的函數(shù)
當(dāng)非常量對象調(diào)用該函數(shù)時,先調(diào)用非常量函數(shù);
當(dāng)常量對象調(diào)用該函數(shù)時,只能調(diào)用常量函數(shù);
如果在類中只有常量函數(shù)而沒有與其同名的非常量函數(shù),則非常量與常量對象都可調(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ù)中。因為構(gòu)造函數(shù)的目的是初始化域值,因此它必須更改對象,析構(gòu)函數(shù)同理

  6.2 常量引用參數(shù)

  本例中,一個myObj類型的對象obj通過引用傳入函數(shù)verifyObjectCorrectness。為安全起見,使用了const關(guān)鍵字來確保函數(shù)verifyObjectCorrectness不會改變對象obj所引用的對象的狀態(tài)。此外,通過聲明參數(shù)常量,函數(shù)的使用者可以確保他們的對象 不會被改變,也不必擔(dān)心在調(diào)用函數(shù)時帶來副作用。以下代碼試圖對聲明為常量引用的形參進行修改,從而不會通過編譯!

#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的值,此行將引起編譯器錯誤 //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ù))中通過引用返回this對象的一個成員, 你應(yīng)該使用常量引用來返回它,即const X&
  也就是說你想通過引用返回的東西如果從邏輯上來講是this對象的一部分(與它是否在物理上嵌入在this對象中無關(guān)),那么常量方法需要通過常量引用或者通過值來返回,而不能通過非常量引用返回

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!!
}

相關(guān)文章

  • c語言輸出字符串中最大對稱子串長度的3種解決方案

    c語言輸出字符串中最大對稱子串長度的3種解決方案

    這篇文章主要介紹了c語言輸出字符串中最大對稱子串長度的3種解決方案,需要的朋友可以參考下
    2014-03-03
  • C?語言的弱符號與弱引用你了解嗎

    C?語言的弱符號與弱引用你了解嗎

    這篇文章主要為大家詳細介紹了C?語言弱符號與弱引用,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 使用C++實現(xiàn)插件模式時的避坑要點(推薦)

    使用C++實現(xiàn)插件模式時的避坑要點(推薦)

    這篇文章主要介紹了使用C++實現(xiàn)插件模式時的避坑要點,本文主要分析實踐中常見的、因為對原理不清楚而搞出來的產(chǎn)品里的坑,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • C語言學(xué)好遞歸看這一篇就夠了

    C語言學(xué)好遞歸看這一篇就夠了

    遞歸指的是在函數(shù)的定義中使用函數(shù)自身的方法,舉個例子: 從前有座山,山里有座廟,廟里有個老和尚,正在給小和尚講故事呢!故事是什么呢?"從前有座山,山里有座廟,廟里有個老和尚,正在給小和尚講故事呢!故事是什么呢?"從前有座山,山里有座廟,循環(huán)下去
    2021-10-10
  • C語言使用posix正則表達式庫的實現(xiàn)

    C語言使用posix正則表達式庫的實現(xiàn)

    在C語言中,你可以使用 POSIX 正則表達式庫(regex.h)來進行正則表達式的模式匹配,本文主要介紹了C語言使用posix正則表達式庫的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 聊聊C語言中sizeof運算符的一個陷阱

    聊聊C語言中sizeof運算符的一個陷阱

    在C語言中,sizeof()是一個判斷數(shù)據(jù)類型或者表達式長度的運算符,下面這篇文章主要給大家介紹了關(guān)于C語言中sizeof運算符的一個陷阱的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-11-11
  • 關(guān)于C++中引用和指針的區(qū)別詳解

    關(guān)于C++中引用和指針的區(qū)別詳解

    這篇文章主要介紹了關(guān)于C++中引用和指針的區(qū)別詳解,
    2023-07-07
  • 帶你從頭學(xué)習(xí)C++的封裝

    帶你從頭學(xué)習(xí)C++的封裝

    這篇文章主要為大家從頭學(xué)習(xí)了C++的封裝,使用數(shù)據(jù)庫,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C++中二進制數(shù)據(jù)序列化和反序列化詳解

    C++中二進制數(shù)據(jù)序列化和反序列化詳解

    這篇文章主要為大家詳細介紹了C++中二進制數(shù)據(jù)序列化和反序列化的相關(guān)知識,文中的示例代碼講解詳細,具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下
    2023-11-11
  • C語言進階教程之字符函數(shù)&字符串函數(shù)

    C語言進階教程之字符函數(shù)&字符串函數(shù)

    C語言提供了豐富的字符串處理函數(shù),可以對字符串進行輸入、輸出、合并、修改、比較、轉(zhuǎn)換、復(fù)制、搜索等操作,下面這篇文章主要給大家介紹了關(guān)于C語言進階教程之字符函數(shù)&字符串函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2022-03-03

最新評論

河西区| 龙泉市| 怀安县| 临海市| 大安市| 彭山县| 含山县| 通榆县| 绥德县| 石景山区| 封丘县| 舞阳县| 常宁市| 武穴市| 荣昌县| 建阳市| 民权县| 葫芦岛市| 来凤县| 翁牛特旗| 清流县| 苏尼特右旗| 峨眉山市| 临城县| 南召县| 象州县| 海兴县| 东源县| 杭锦后旗| 江川县| 桐城市| 通化县| 铅山县| 牟定县| 垫江县| 大理市| 星子县| 石狮市| 乐昌市| 北京市| 佛山市|