1. 程式人生 > >C++對象生存期&&static

C++對象生存期&&static

定義 作用域 共享 class 標識符 vat stat object c pri

生存期即從誕生到消失的時間段,在生存期內,對象的值或保持不變,知道改變他的值為止。對象生存期分為靜態生存期動態生存期兩種。

  • 靜態生存期

指對象的生存期與程序運行期相同。在namespace中聲明的對象都具有靜態生存期。但是,在函數內部作用域中聲明具有動態生存期的對象,要用static修飾,如static int a

在局部作用域中,靜態變量的特點是不會隨函數的每次調用而產生一個副本,同時也不會因為函數的返回而消失。該變量會一直保持上一個值,在每次調用中可共享。同時靜態變量在定義時也可以賦值,如static int a = 3;

  • 動態生存期

除上述兩種情況,其余為動態生存期。在局部作用域中,有動態生存期的對象,也稱為局部生存期對象。局部生存期對象誕生於聲明點,結束於聲明塊執行完畢。在類中不用static修飾的成員,他們的生存期和對象生存期一致。

例:

#include<iostream>
using namespace std;
int i =1;//i全局變量,動態生存期
void Other()
{
    static int a = 2;
    static int b ;//a,b為靜態局部變量,全局壽命,局部可見,第一次進入函數時初始化
    int c = 10;//c局部變量,動態生存期,每次進入函數都初始化
    a+=2;
    i+=32;
    c+=5;
    cout<<"Other:"<<endl;
    cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
}
int main()
{
    static int a;//靜態局部變量,全局壽命,局部可見
    int b= -1;
    int c = 0;;//b,c局部變量,動態生存期
    cout<<"Main:"<<endl;
    cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
    c+=8;
    Other();
    cout<<"Main:"<<endl;
    cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
    i+=10;
    Other();
    return 0;
}

  運行結果

技術分享圖片


類的靜態成員

類的靜態成員是解決同一個類的不同對象之間數據和函數的共享問題的。如每生成一個對象,則計數+1,從而統計一共創建了多少個對象。

  • 靜態數據成員

在類的一個屬性中,如果某個屬性為整個類所共享,則用static修飾為靜態成員。該成員在每個類中只有一個副本,由所有對象共同維護,從而實現數據共享。

靜態數據成員具有靜態生存期,因為靜態數據成員不屬於任何對象,可通過類名訪問,”類名::標識符“。另外,在類定義中,僅進行引用性聲明,而在namespace作用域中使用類名限定定義性聲明,或初始化。(原因:這樣定義是因為這種方式要專門分配空間,非靜態數據成員的空間與所屬對象空間是同時分配的,所以無須這樣定義)。

例:

#include<iostream>
using namespace std;
class Point
{
public:
    Point(int x  = 0,int y = 0):x(x),y(y)
    {
        count++;
    }
    Point(Point &p)//copy
    {
        x = p.x;
        y = p.y;
        count++;
    }
    ~Point()
    {
        count --;
    }
    int GetX(){return x;}
    int GetY(){return y;}
    void ShowCount()//靜態函數
    {
        cout<<"Object count :"<<count<<endl;
    }
private:
    static int  count;//static
    int x;
    int y;
};

int Point:: count = 0;//靜態數據成員的初始化,類名限定

int main()
{
    Point a(4,5);
    cout<<"Pont a:"<<"("<<a.GetX()<<","<<a.GetY()<<")"<<endl;
    a.ShowCount();//通過對象名
    Point b(a);
    cout<<"Pont b:"<<"("<<b.GetX()<<","<<b.GetY()<<")"<<endl;
    b.ShowCount();
    return 0;
}

  運行結果

技術分享圖片

  • 靜態函數成員

在上面例子中,ShowCount()是輸出count的值的,而在所有對象聲明前,count是==0的,那麽如果輸出這時的count,該怎麽做??所以這時靜態函數成員就起作用了。

修改如下:

class Point
{
public:
    .
    .
    .
    static void ShowCount()//靜態函數
    {
        cout<<"Object count :"<<count<<endl;
    }
private:
   ...
};

int Point:: count = 0;//靜態數據成員的初始化,類名限定
int main()
{   
    Point::ShowCount();
    Point a(4,5);
    cout<<"Pont a:"<<"("<<a.GetX()<<","<<a.GetY()<<")"<<endl;
    Point::ShowCount();
    Point b(a);
    cout<<"Pont b:"<<"("<<b.GetX()<<","<<b.GetY()<<")"<<endl;
    Point::ShowCount();
    return 0;
}

  運行結果

技術分享圖片

在ShowPoint()函數前加一個static,即變為靜態成員函數,它也屬於整個類,有所有對象共同擁有,為所有對象共享。靜態成員函數可以用過類名|對象名訪問,非靜態成員函數只能通過對象名調用。

另外,靜態成員函數可以直接訪問類的靜態數據和函數成員,而訪問非靜態成員,必須通過對象名。所以一般情況下,靜態函數用來訪問類的靜態數據成員

C++對象生存期&&static