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

深入解析C++編程中的靜態(tài)成員函數(shù)

 更新時間:2015年09月17日 16:41:27   投稿:goldensun  
這篇文章主要介紹了深入解析C++編程中的靜態(tài)成員函數(shù),是C++入門學(xué)習中的基礎(chǔ)知識,需要的朋友可以參考下

C++靜態(tài)成員函數(shù)

與數(shù)據(jù)成員類似,成員函數(shù)也可以定義為靜態(tài)的,在類中聲明函數(shù)的前面加static就成了靜態(tài)成員函數(shù)。如

  static int volume( );


和靜態(tài)數(shù)據(jù)成員一樣,靜態(tài)成員函數(shù)是類的一部分,而不是對象的一部分。

如果要在類外調(diào)用公用的靜態(tài)成員函數(shù),要用類名和域運算符“::”。如

  Box::volume( );


實際上也允許通過對象名調(diào)用靜態(tài)成員函數(shù),如

  a.volume( );


但這并不意味著此函數(shù)是屬于對象a的,而只是用a的類型而已。

與靜態(tài)數(shù)據(jù)成員不同,靜態(tài)成員函數(shù)的作用不是為了對象之間的溝通,而是為了能處理靜態(tài)數(shù)據(jù)成員。

我們知道,當調(diào)用一個對象的成員函數(shù)(非靜態(tài)成員函數(shù))時,系統(tǒng)會把該對象的起始地址賦給成員函數(shù)的this指針。而靜態(tài)成員函數(shù)并不屬于某一對象,它與任何對象都無關(guān),因此靜態(tài)成員函數(shù)沒有this指針。既然它沒有指向某一對象,就無法對一個對象中的非靜態(tài)成員進行默認訪問(即在引用數(shù)據(jù)成員時不指定對象名)。

可以說,靜態(tài)成員函數(shù)與非靜態(tài)成員函數(shù)的根本區(qū)別是:非靜態(tài)成員函數(shù)有this指針,而靜態(tài)成員函數(shù)沒有this指針。由此決定了靜態(tài)成員函數(shù)不能訪問本類中的非靜態(tài)成員。

靜態(tài)成員函數(shù)可以直接引用本類中的靜態(tài)數(shù)據(jù)成員,因為靜態(tài)成員同樣是屬于類的,可以直接引用。在C++程序中,靜態(tài)成員函數(shù)主要用來訪問靜態(tài)數(shù)據(jù)成員,而不訪問非靜態(tài)成員。

假如在一個靜態(tài)成員函數(shù)中有以下語句:

  cout<<height<<endl; //若height已聲明為static,則引用本類中的靜態(tài)成員,合法
  cout<<width<<endl; //若width是非靜態(tài)數(shù)據(jù)成員,不合法


但是,并不是絕對不能引用本類中的非靜態(tài)成員,只是不能進行默認訪問,因為無法知道應(yīng)該去找哪個對象。

如果一定要引用本類的非靜態(tài)成員,應(yīng)該加對象名和成員運算符“.”。如

  cout<<a.width<<endl; //引用本類對象a中的非靜態(tài)成員


假設(shè)a已定義為Box類對象,且在當前作用域內(nèi)有效,則此語句合法。

通過下面這個例子可以具體了解有關(guān)引用非靜態(tài)成員的具體方法。

[例] 靜態(tài)成員函數(shù)的應(yīng)用。

#include <iostream>
using namespace std;
class Student          //定義Student類
{
public:
  Student(int n,int a,float s):num(n),age(a),score(s){ }   //定義構(gòu)造函數(shù)
  void total( );
  static float average( );   //聲明靜態(tài)成員函數(shù)
private:
  int num;
  int age;
  float score;
  static float sum;      //靜態(tài)數(shù)據(jù)成員
  static int count;      //靜態(tài)數(shù)據(jù)成員
};
void Student::total( )           //定義非靜態(tài)成員函數(shù)
{
  sum+=score;              //累加總分
  count++;                //累計已統(tǒng)計的人數(shù)
}
float Student::average( )         //定義靜態(tài)成員函數(shù)
{
  return(sum/count);
}
float Student::sum=0;           //對靜態(tài)數(shù)據(jù)成員初始化
int Student::count=0;           //對靜態(tài)數(shù)據(jù)成員初始化
int main( )
{
  Student stud[3]={           //定義對象數(shù)組并初始化
   Student(1001,18,70),
   Student(1002,19,78),
   Student(1005,20,98)
  };
  int n;
  cout<<"please input the number of students:";
  cin>>n;                //輸入需要求前面多少名學(xué)生的平均成績
  for(int i=0;i<n;i++)         //調(diào)用3次total函數(shù)
   stud[i].total( );
  cout<<"the average score of "<<n<<" students is "<<Student::average( )<<endl;
  //調(diào)用靜態(tài)成員函數(shù)
  return 0;
}

運行結(jié)果為:

please input the number of students:3↙
the average score of 3 students is 82.3333

關(guān)于靜態(tài)成員函數(shù)成員的幾點說明:
在主函數(shù)中定義了stud對象數(shù)組,為了使程序簡練,只定義它含3個元素,分別存放3個學(xué)生的數(shù)據(jù)。程序的作用是先求用戶指定的n名學(xué)生的總分,然后求平均成績(n由用戶輸入)。
在Student類中定義了兩個靜態(tài)數(shù)據(jù)成員sum(總分)和count(累計需要統(tǒng)計的學(xué)生人數(shù)), 這是由于這兩個數(shù)據(jù)成員的值是需要進行累加的,它們并不是只屬于某一個對象元素,而是由各對象元素共享的,可以看出: 它們的值是在不斷變化的,而且無論對哪個對象元素而言,都是相同的,而且始終不釋放內(nèi)存空間。
total是公有的成員函數(shù),其作用是將一個學(xué)生的成績累加到sum中。公有的成員函數(shù)可以引用本對象中的一般數(shù)據(jù)成員(非靜態(tài)數(shù)據(jù)成員),也可以引用類中的靜態(tài)數(shù)據(jù)成員。score是非靜態(tài)數(shù)據(jù)成員,sum和count是靜態(tài)數(shù)據(jù)成員。
average是靜態(tài)成員函數(shù),它可以直接引用私有的靜態(tài)數(shù)據(jù)成員(不必加類名或?qū)ο竺?, 函數(shù)返回成績的平均值。
在main函數(shù)中,引用total函數(shù)要加對象名(今用對象數(shù)組元素名), 引用靜態(tài)成員函數(shù)average函數(shù)要用類名或?qū)ο竺?br /> 請思考,如果不將average函數(shù)定義為靜態(tài)成員函數(shù)行不行?程序能否通過編譯?需要作什么修改?為什么要用靜態(tài)成員函數(shù)?請分析其理由。

C++ static靜態(tài)成員變量和靜態(tài)成員函數(shù)
一般情況下,如果有N個同類的對象,那么每一個對象都分別有自己的成員變量,不同對象的成員變量各自有值,互不相干。但是有時我們希望有某一個或幾個成員變量為所有對象共有,這樣可以實現(xiàn)數(shù)據(jù)共享。

可以使用全局變量來達到共享數(shù)據(jù)的目的。例如在一個程序文件中有多個函數(shù),每一個函數(shù)都可以改變?nèi)肿兞康闹?,全局變量的值為各函?shù)共享。但是用全局變量的安全性得不到保證,由于在各處都可以自由地修改全局變量的值,很有可能偶然失誤,全局變量的值就被修改,導(dǎo)致程序的失敗。因此在實際開發(fā)中很少使用全局變量。

如果想在同類的多個對象之間實現(xiàn)數(shù)據(jù)共享,也不要用全局變量,那么可以使用靜態(tài)成員變量。
static靜態(tài)成員變量

靜態(tài)成員變量是一種特殊的成員變量,它以關(guān)鍵字 static 開頭。例如:

class Student{
private:
  char *name;
  int age;
  float score;
  static int num; //將num定義為靜態(tài)成員變量
public:
  Student(char *, int, float);
  void say();
};

這段代碼聲明了一個靜態(tài)成員變量 num,用來統(tǒng)計學(xué)生的人數(shù)。

static 成員變量屬于類,不屬于某個具體的對象,這就意味著,即使創(chuàng)建多個對象,也只為 num 分配一份內(nèi)存,所有對象使用的都是這份內(nèi)存中的數(shù)據(jù)。當某個對象修改了 num,也會影響到其他對象。

static 成員變量必須先初始化才能使用,否則鏈接錯誤。例如:

int Student::num; //初始化


也可以在初始化時賦初值:

int Student::num = 10; //初始化同時賦值


初始化時可以不加 static,但必須要有數(shù)據(jù)類型。被 private、protected、public 修飾的 static 成員變量都可以用這種方式初始化。

注意:static 成員變量的內(nèi)存空間既不是在聲明類時分配,也不是在創(chuàng)建對象時分配,而是在初始化時分配。

static 成員變量既可以通過對象來訪問,也可以通過類來訪問。通過類來訪問的形式為:

類名::成員變量;


例如:

//通過類來訪問
Student::num = 10;
//通過對象來訪問
Student stu;
stu.num = 10;


這兩種方式是等效的。

注意:static 成員變量與對象無關(guān),不占用對象的內(nèi)存,而是在所有對象之外開辟內(nèi)存,即使不創(chuàng)建對象也可以訪問。

下面來看一個完整的例子:

#include <iostream>
using namespace std;
class Student{
private:
  char *name;
  int age;
  float score;
  static int num; //將num定義為靜態(tài)成員變量
public:
  Student(char *, int, float);
  void say();
};
int Student::num = 0; //初始化靜態(tài)成員變量
Student::Student(char *name, int age, float score){
  this->name = name;
  this->age = age;
  this->score = score;
  num++;
}
void Student::say(){
  //在普通成員函數(shù)中可以訪問靜態(tài)成員變量
  cout<<name<<"的年齡是 "<<age<<",成績是 "<<score<<"(當前共"<<num<<"名學(xué)生)"<<endl;
}
int main(){
  //使用匿名對象
  (new Student("小明", 15, 90))->say();
  (new Student("李磊", 16, 80))->say();
  (new Student("張華", 16, 99))->say();
  (new Student("王康", 14, 60))->say();
  return 0;
}

運行結(jié)果:

小明的年齡是 15,成績是 90(當前共1名學(xué)生)
李磊的年齡是 16,成績是 80(當前共2名學(xué)生)
張華的年齡是 16,成績是 99(當前共3名學(xué)生)
王康的年齡是 14,成績是 60(當前共4名學(xué)生)

本例中將 num 聲明為靜態(tài)成員變量,每次創(chuàng)建對象時,會調(diào)用構(gòu)造函數(shù),將 num 的值加 1。之所以使用匿名對象,是因為每次創(chuàng)建對象后只會使用它的 say 函數(shù),不再進行其他操作。不過請注意,使用匿名對象有內(nèi)存泄露的風險。

關(guān)于靜態(tài)數(shù)據(jù)成員的幾點說明:
1) 一個類中可以有一個或多個靜態(tài)成員變量,所有的對象都共享這些靜態(tài)成員變量,都可以引用它。

2) static 成員變量和普通 static 變量一樣,編譯時在靜態(tài)數(shù)據(jù)區(qū)分配內(nèi)存,到程序結(jié)束時才釋放。這就意味著,static 成員變量不隨對象的創(chuàng)建而分配內(nèi)存,也不隨對象的銷毀而釋放內(nèi)存。而普通成員變量在對象創(chuàng)建時分配內(nèi)存,在對象銷毀時釋放內(nèi)存。

3) 靜態(tài)成員變量必須初始化,而且只能在類體外進行。例如:

int Student::num = 10;


初始化時可以賦初值,也可以不賦值。如果不賦值,那么會被默認初始化,一般是 0。靜態(tài)數(shù)據(jù)區(qū)的變量都有默認的初始值,而動態(tài)數(shù)據(jù)區(qū)(堆區(qū)、棧區(qū))的變量默認是垃圾值。

4) 靜態(tài)成員變量既可以通過對象名訪問,也可以通過類名訪問,但要遵循 private、protected 和 public 關(guān)鍵字的訪問權(quán)限限制。當通過對象名訪問時,對于不同的對象,訪問的是同一份內(nèi)存。
static靜態(tài)成員函數(shù)

在類中,static 除了聲明靜態(tài)成員變量,還可以聲明靜態(tài)成員函數(shù)。普通成員函數(shù)可以訪問所有成員變量,而靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量。

我們知道,當調(diào)用一個對象的成員函數(shù)(非靜態(tài)成員函數(shù))時,系統(tǒng)會把當前對象的起始地址賦給 this 指針。而靜態(tài)成員函數(shù)并不屬于某一對象,它與任何對象都無關(guān),因此靜態(tài)成員函數(shù)沒有 this 指針。既然它沒有指向某一對象,就無法對該對象中的非靜態(tài)成員進行訪問。

可以說,靜態(tài)成員函數(shù)與非靜態(tài)成員函數(shù)的根本區(qū)別是:非靜態(tài)成員函數(shù)有 this 指針,而靜態(tài)成員函數(shù)沒有 this 指針。由此決定了靜態(tài)成員函數(shù)不能訪問本類中的非靜態(tài)成員。

靜態(tài)成員函數(shù)可以直接引用本類中的靜態(tài)數(shù)據(jù)成員,因為靜態(tài)成員同樣是屬于類的,可以直接引用。在C++程序中,靜態(tài)成員函數(shù)主要用來訪問靜態(tài)數(shù)據(jù)成員,而不訪問非靜態(tài)成員。

如果要在類外調(diào)用 public 屬性的靜態(tài)成員函數(shù),要用類名和域解析符“::”。如:

Student::getNum();

當然也可以通過對象名調(diào)用靜態(tài)成員函數(shù),如:

stu.getNum();

下面是一個完整的例子,通過靜態(tài)成員函數(shù)獲得學(xué)生的平均成績:

#include <iostream>
using namespace std;
class Student{
private:
  char *name;
  int age;
  float score;
  static int num; //學(xué)生人數(shù)
  static float total; //總分
public:
  Student(char *, int, float);
  void say();
  static float getAverage(); //靜態(tài)成員函數(shù),用來獲得平均成績
};
int Student::num = 0;
float Student::total = 0;
Student::Student(char *name, int age, float score){
  this->name = name;
  this->age = age;
  this->score = score;
  num++;
  total += score;
}
void Student::say(){
  cout<<name<<"的年齡是 "<<age<<",成績是 "<<score<<"(當前共"<<num<<"名學(xué)生)"<<endl;
}
float Student::getAverage(){
  return total / num;
}
int main(){
  (new Student("小明", 15, 90))->say();
  (new Student("李磊", 16, 80))->say();
  (new Student("張華", 16, 99))->say();
  (new Student("王康", 14, 60))->say();
  cout<<"平均成績?yōu)?"<<Student::getAverage()<<endl;
  
  return 0;
}

運行結(jié)果:

小明的年齡是 15,成績是 90(當前共1名學(xué)生)
李磊的年齡是 16,成績是 80(當前共2名學(xué)生)
張華的年齡是 16,成績是 99(當前共3名學(xué)生)
王康的年齡是 14,成績是 60(當前共4名學(xué)生)
平均成績?yōu)?82.25

上面的代碼中,將 num、total 聲明為靜態(tài)成員變量,將 getAverage 聲明為靜態(tài)成員函數(shù)。在 getAverage 函數(shù)中,只使用了 total、num 兩個靜態(tài)成員變量。

相關(guān)文章

  • C++共用體的定義與應(yīng)用總結(jié)

    C++共用體的定義與應(yīng)用總結(jié)

    共同體的定義類似結(jié)構(gòu)體,不過共同體的所有成員都在同一段內(nèi)存中存放,起始地址一樣,并且同一時刻只能使用其中的一個成員變量
    2013-10-10
  • C++實現(xiàn)通訊錄管理系統(tǒng)設(shè)計

    C++實現(xiàn)通訊錄管理系統(tǒng)設(shè)計

    這篇文章主要為大家詳細介紹了C++實現(xiàn)通訊錄管理系統(tǒng)設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語言實現(xiàn)簡易掃雷程序

    C語言實現(xiàn)簡易掃雷程序

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)簡易掃雷程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 一波C語言二元查找樹算法題目解答實例匯總

    一波C語言二元查找樹算法題目解答實例匯總

    這篇文章主要介紹了一波C語言二元查找樹算法題目解答實例匯總,包括按層次遍歷和轉(zhuǎn)換為鏡像等基本算法題目,需要的朋友可以參考下
    2016-03-03
  • C++ 內(nèi)存分區(qū)模型的使用(代碼區(qū)、全局區(qū)、棧區(qū)、堆區(qū)、new)

    C++ 內(nèi)存分區(qū)模型的使用(代碼區(qū)、全局區(qū)、棧區(qū)、堆區(qū)、new)

    這篇文章主要介紹了C++ 內(nèi)存分區(qū)模型的使用(代碼區(qū)、全局區(qū)、棧區(qū)、堆區(qū)、new),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2021-04-04
  • C語言數(shù)組入門之數(shù)組的聲明與二維數(shù)組的模擬

    C語言數(shù)組入門之數(shù)組的聲明與二維數(shù)組的模擬

    這篇文章主要介紹了C語言數(shù)組入門之數(shù)組的聲明與二維數(shù)組的模擬,數(shù)組學(xué)習的同時也要相應(yīng)理解C語言指針的作用,需要的朋友可以參考下
    2015-12-12
  • C語言實現(xiàn)電子英漢詞典系統(tǒng)

    C語言實現(xiàn)電子英漢詞典系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)電子英漢詞典系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語言實現(xiàn)數(shù)學(xué)表達式運算

    C語言實現(xiàn)數(shù)學(xué)表達式運算

    這篇文章主要為大家詳細介紹了c語言實現(xiàn)數(shù)學(xué)表達式運算,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C語言實現(xiàn)排序算法之歸并排序詳解

    C語言實現(xiàn)排序算法之歸并排序詳解

    這篇文章主要介紹了C語言實現(xiàn)排序算法之歸并排序,對歸并排序的原理及實現(xiàn)過程做了非常詳細的解讀,需要的朋友可以參考下
    2014-07-07
  • C++自動析構(gòu)時的順序問題

    C++自動析構(gòu)時的順序問題

    這篇文章主要介紹了C++自動析構(gòu)時的順序,通過實例代碼給大家講解了C++ 構(gòu)造與析構(gòu)的執(zhí)行順序,代碼簡單易懂,非常不錯對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03

最新評論

潞西市| 靖远县| 罗山县| 海伦市| 易门县| 湖州市| 吴堡县| 瑞昌市| 渑池县| 丰都县| 富民县| 义乌市| 沙河市| 桓仁| 外汇| 鄯善县| 始兴县| 合肥市| 灵寿县| 纳雍县| 万宁市| 满城县| 若尔盖县| 巴东县| 海伦市| 公安县| 嘉善县| 德惠市| 富锦市| 慈利县| 泾源县| 沈阳市| 云梦县| 高雄市| 资源县| 维西| 平利县| 西昌市| 前郭尔| 小金县| 渝中区|