天天看點

3-C++程式的結構1.2

對象的生存周期

可以分為靜态生存周期和動态生存周期

1、靜态生存周期

如果對象的生存期與程式的運作期相同,我們稱它具有靜态生存期。在檔案作用域中聲明的對象都具有靜态生存期的。如果要在函數的塊中聲明具有靜态生存期的對象,則要使用關鍵字static。

2、動态生存期

除了上述兩種情況,其餘的對象都具有動态生存期。動态生存期對象誕生于聲明點,結束于該标示符作用域結束處。

類的靜态成員

在結構化的程式設計中程式子產品的基本機關是函數,那麼子產品間對記憶體中資料的共享是通過函數與函數之間的資料共享來實作的,包括參數傳遞和全局變量。

靜态成員是解決同一個類的不同對象之間資料和函數共享問題的。如,把某公司的全體雇員抽象如下,

class employee
{
  private:
    int EmpNo;
    int ID;
    char *name;
    //...
}      

這時,如果需要統計全體員工的總數,該怎麼處理呢,如果直接加上一個變量到類裡面,勢必會造成每個對象都會包含此變量,而且容易造成不一緻,比較理想的方案是類的所有對象共同擁有一個用于存放總數的資料成員,這就是需要借助靜态資料成員。

1、靜态資料成員

我們說“一個類的所有對象具有相同的屬性”,是指屬性的個數、名稱、資料類型相同,各個對象的屬性值則可以不相同,這樣的屬性在面向對象方法中稱為“執行個體屬性”。在c++程式中以類的非靜态資料成員表示。

面向對象方法中還有“類屬性”的概念。如果某個屬性為整個類所共有,不屬于任何一個具體對象,則采用static關鍵字來聲明靜态成員。靜态成員在每一個類隻有一個拷貝,由該類的所有對象共同維護和使用,進而實作了同一類的不同對象之間的資料共享。類屬性是描述類的所有對象共同特征的一個資料項,對于任何對象執行個體,它的屬性是相同的。

靜态資料成員具有靜态生存周期。它隻能通過類名進行通路,一般的用法是“類名::辨別符”。在類的定義中僅僅對靜态資料成員進行聲明,必須在檔案作用域的某個地方使用類名限定對靜态資料成員進行定義,這時也可以進行初始化。

2、靜态函數成員

所謂靜态成員函數就是使用static關鍵字聲明的函數成員,同靜态資料成員一樣,靜态成員函數頁屬于整個類,由同一個類的所有對象共同擁有,為這些對象所共享。

作為成員函數,它的通路屬性可以受到類的嚴格控制,對于公有的靜态成員函數,可以通過類名或對象名來調用,而一般的非靜态成員函數隻能通過對象名來調用。

靜态成員函數可以直接通路類的靜态資料和函數成員。而通路非靜态資料成員必須通過參數傳遞方式得到對象名,然後通過對象名來通路。如,

class A
{
  public:
    static void f(A a);
  private:
    int x;
};
void A::f(A a)
{
  cout<<x;//對x的引用時錯誤的
  cout<<a.x;//正确
}      
#include<iostream>
using namespace std;
class Point              //Point類定義
{
public:
  Point(int xx=0,int yy=0){X=xx;Y=yy;countP++;} //構造函數
  Point(Point &p);    //拷貝構造函數
  ~Point(){countP--;}
  int GetX(){return X;}
  int GetY(){return Y;}
  static void GetC(){cout<<"Object id="<<countP<<endl;}private:
  int X,Y;
  static int countP;

};
Point::Point(Point &p)
{
  X=p.X;
  Y=p.Y;
  countP++;
}
int Point::countP=0; //靜态資料成員定義及初始化,初始化使用類名限定
int main()
{
  Point A(4,5);
  cout<<"Point A,"<<A.GetX()<<","<<A.GetY();
  A.GetC();
  Point B(A);
  cout<<"Point B,"<<B.GetX()<<","<<B.GetY();
  Point::GetC();
  return 0;
}      

繼續閱讀