C++におけるstaticの役割(オブジェクト向け)

3670 ワード

オブジェクト向け設計におけるstatic
1.静的メンバー変数
(1)静的メンバー変数はクラス全体に属するグローバル変数であり、すべてのオブジェクトによって共有され、あるオブジェクトに属しない.通常のメンバー変数はオブジェクトに属する変数であり、すべてのオブジェクトによって共有されない.
#include<iostream>
using namespace std;
class A
{
public:
      static int x;
};

int A::x = 10;  //         x
int main()
{
   A a, b, c;
   cout<<a.x<<endl<<b.x<<endl<<c.x;
   return 0;
}

このクラスの3つのオブジェクトa,b,cは静的メンバー変数xを共有する.
(2)静的メンバー変数を使用する場合は,特定のオブジェクトに限定されず,クラス名のみに連用すればよい.
A::x;いいえ:A a;a.x;
(3)静的メンバー変数は、オブジェクトがない前に存在します.
#include<iostream>
using namespace std;
class A
{
public:
      static int n;
};

int A::n = 0;  //         n
int main()
{
    int i;
    for(i=0; i<5; i++)
    {
        A::n++;
        cout<<A::n<<"  ";
    }
    return 0;
}

出力:1 2 3 4 5
前述の例では、オブジェクトは作成されず、静的メンバー変数nにクラス名と制限子でアクセスし、静的メンバー変数がオブジェクトがない前に存在することを示す自己加算を行います.
(4)プライベート静的メンバー変数:クラス外のすべての関数にアクセスさせたくない場合は、クラスの共通メンバー関数のみがアクセスできるようにプライベートとして宣言できますが、クラスのオブジェクトを作成する必要があることを前提としています.
#include<iostream>
using namespace std;
class A
{
public:
      void func() {cout<<A::x;}  //              x
private:
      static int x;
};

int A::x = 1000;  //         x
int main()
{
   A a;
   a.func();
   return 0;
}

静的データ・メンバーの使用には、グローバル変数と比較して2つの利点があります.
 1.静的データメンバーはプログラムのグローバル名前空間に入っていないため、プログラム内の他のグローバル名前と衝突する可能性はありません. 
 2.情報の非表示を実現できます.静的データ・メンバーはprivateメンバーであり、グローバル変数はできません.
 
2.静的メンバー関数(1)静的メンバー関数は、1つのオブジェクトではなくクラス全体に属する静的メンバー変数と同じです.
#include<iostream>
using namespace std;
class A
{
public:
      void static show() {cout<<A::n; n++;} //      show(),          n  n  
private:
      static int n;
};
int A::n = 0;
int main()
{
    int i;
    for(i=0; i<5; i++)
    {
        A::show();
    }
    return 0;
}

出力:01234
上記の例から分かるように、共通の静的メンバー関数show()は、オブジェクトが作成されていない場合にも使用でき、その呼び出しは静的メンバー変数と同じである.
オブジェクトから静的メンバー関数にアクセスすることもできます.
A a,b;    a.show();    b.show();
(2)通常のメンバー関数には、通常のメンバー関数が常に特定のクラスの特定のオブジェクトに属するため、クラスのオブジェクト自体を指すthisポインタが隠されています.通常、thisはデフォルトです.関数fn()のように実際にはthis->fn()です.しかし、通常の関数と比較すると、静的メンバー関数は任意のオブジェクトに関連付けられていないため、thisポインタはありません.この意味では、クラスオブジェクトに属する非静的データ・メンバーにも非静的メンバー関数にもアクセスできません.
#include<iostream>
using namespace std;
class A
{
public:
      void show(int i) {x = i; cout<<x;}
      //void static show1(int j) {x = j; cout <<x;}
      //             this  ,             x
private:
      int x;
};

int main()
{
     A a;
     a.show(1);
     //a.show1(1);
     return 0;
}

7行目は静的メンバー関数show 1()を定義し、この関数内でthisポインタでオブジェクトのメンバー変数xにアクセスしようとすると、エラーが報告されるので注釈した.
    
注意:
      1.静的メンバー間で相互にアクセスできます.静的メンバー関数から静的メンバー変数へのアクセスと静的メンバー関数へのアクセスが含まれます.
  2.非静的メンバー関数は、静的メンバー関数および静的メンバー変数に任意にアクセスできます.
  3.静的メンバー関数は、非静的メンバー関数および非静的メンバー変数にアクセスできません.
  4.thisポインタの追加オーバーヘッドがないため、静的メンバー関数はクラスのグローバル関数に比べて速度的にわずかに増加します.
      5.静的メンバー関数を虚関数として定義することはできません.
      6.静的メンバーの初期化は一般的なデータメンバーの初期化とは異なり、初期化はクラスの外で行われ、一般的な静的変数やオブジェクトと混同されないようにstaticは加算されません.初期化時に役割ドメイン演算子を使用して、その属するクラスを明記します.