C++程序設計必知:作用域和可見性

       這些必知的知識包括作用域、可見性和生存期,還有局部變量、全局變量、類的數據成員、靜態成員及友元和數據等。作用域是用來表示某個標識符在什麼範圍內有效,可見性是指標識符是否可見,可引用。

       1.作用域

       作用域是這樣一個區域,標識符在程序的這個區域內是有效的。C++的作用域主要有四種:函數原型作用域、塊作用域、類作用域和文件作用域。

       a.函數原型作用域

       函數原型比如:void fun(int x);這個語句就是函數原型的聲明。函數原型聲明中的形參的作用範圍就是函數原型作用域。fun函數中形參x有效的範圍就在左、右兩個括號之間,出了這兩個括號,在程序的其他地方都無法引用x。標識符x的作用域就是所謂的函數原型作用域。函數原型如果有形參,聲明時一定要有形參的類型說明,但是形參名比如x可以省略,不會對程序有任何影響,一般爲了程序可讀性好,我們一般都寫上一個容易理解的形參名。函數原型作用域是最小的作用域。

       b.塊作用域

       這裏說的塊就是一對大括號括起來的一段程序,塊中聲明的標識符在什麼範圍內有效呢?從標識符聲明處到塊結束的大括號之間都有效。也就是說塊中標識符的作用域就是從標識符聲明處開始,到塊結束的大括號爲止。舉個例子說明下:

        void fun(int x)
        {  
                 int a(x);               // a的作用域開始
                 cin>>a;
                 if (a>0)
                 {
                          int b;          // b的作用域開始
                          ......
                 }                          // b的作用域結束
        }                                   // a的作用域結束

       在fun的函數體內聲明瞭整型變量a,又在if語句的分支內聲明瞭變量b,a和b都具有塊作用域,但是它們的塊作用域並不同。a的作用域從其聲明處開始,到其所在塊的結束處也就是整個函數體結束的地方爲止,b的作用域是從b聲明處開始到其所在塊結束也就是if分支體結束的地方爲止。

  c.類作用域

       假設有一個類A,A中有一個數據成員x,x在A的所有函數成員中都有效,除非函數成員中也定義了一個名稱爲x的變量,這樣的x就具有類作用域。爲什麼要排除含有另一個名稱也爲x的變量的函數成員呢?因爲那樣的話A的數據成員x在此函數成員被函數成員中的另一個x覆蓋,不可見了。

       函數成員訪問的大多數數據成員都具有類作用域。我們一般用a.x的方式訪問類A的對象a的數據成員x,這裏的x就具有類作用域。

       符號“.”用於訪問對象的成員,包括函數成員。比如,a.fun(x)用來調用對象a的函數fun。如果ptr是指向類A的一個對象的指針,則訪問其數據成員x的方式爲ptr->x,訪問函數成員的形式如:ptr->fun(x)。

       d.文件作用域

       如果一個標識符沒有在前三種作用域中出現,則它具有文件作用域。這種標識符的作用域從聲明處開始,到文件結尾處結束。

      舉個例子說明下文件作用域:

  1.         #include<iostream>
  2.         using namespace std;
  3.         int i;   //文件作用域
  4.         int main()
  5.         { 
  6.                  i=1;
  7.                  {                                              //子塊
  8.                          int i;                                //塊作用域
  9.                          i=2;
  10.                          cout<<"i="<<i<<endl;  //輸出2
  11.                  }
  12.                  cout<<"i="<<i;   //輸出1
  13.                  return 0;
  14.          }

       上面的例子中,在main函數之前聲明瞭變量i,i在整個源文件中都有效,即它具有文件作用域。而在子塊中也聲明一個變量i,這個i具有塊作用域。進入main函數後給i賦了初值1,在子塊中又聲明了一個同名變量i,並賦初值2,第一次輸出i時輸出i=2,爲什麼呢?因爲子塊裏具有塊作用域的i把外面具有文件作用域的i屏蔽掉了,就是說在子塊中,具有文件作用域的i是不可見的。出了子塊後,具有塊作用域的i就無效了,所以就輸出具有文件作用域的i的值i=1。

        2.可見性

       標識符的可見性是指在程序的某個地方是否是有效的,是否能夠被引用被訪問。程序運行到某一處時,能夠訪問的標識符就是在此處可見的標識符。

       上面說的四種作用域中,最大的是文件作用域,其次是類作用域,再次是塊作用域。它們的包含關係是:

雞啄米:C++編程入門系列之十八(C++程序設計必知:作用域和可見性)

       作用域可見性要注意的幾點是:
       a.我們要引用標識符時,必須先聲明標識符。
       b.在一個作用域內,不能聲明多於一個的同名的標識符。
       c.在不同的作用域,並且這些作用域間沒有互相包含關係,則可以在其中聲明同名標識符,這些同名標識符不會互相影響。
       d.如果在有包含關係的作用域中聲明了同名標識符,則外層作用域中的標識符在內層作用域中不可見。

       我們再來看下文件作用域中的那個例子,此例就是文件作用域中包含了塊作用域的例子。在子塊之前可以引用具有文件作用域的變量i,此時它是可見的,但是進入子塊後,就只能引用具有塊作用域的變量i了,這時具有文件作用域的變量i就不可見了,這就是上面d中說的外層的標識符被內層的同名標識符屏蔽,這也叫做同名覆蓋。

       

發佈了39 篇原創文章 · 獲贊 7 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章