C++クラスの静的メンバー変数と静的メンバー関数の役割


データ・メンバーは、静的変数、非静的変数の2つに分けることができます.
≪静的メンバー|Static Members|emdw≫:静的クラスのメンバーがstatic修飾子、すなわち静的メンバーに追加され、クラス名+静的メンバー名を使用して静的メンバーにアクセスできます.静的メンバーはメモリに存在し、非静的メンバーはインスタンス化されてメモリを割り当てる必要があるため、静的メンバーは非静的メンバーにアクセスできません.静的メンバーはメモリに存在するため、したがって、非静的メンバーはクラス内の静的メンバーに直接アクセスできます.
非静的メンバー:staticを付けていないメンバーはすべて非静的メンバーであり、クラスがインスタンス化された後、インスタンス化されたクラス名でアクセスできます.非静的メンバーの生存期間はクラスの生存期間に決定されますが、静的メンバーは常にメモリに存在するため、生存期間の概念は存在しません.
1つのクラスには静的メンバーと非静的メンバーを含めることができ、クラスには静的構造関数と非静的構造関数も含まれます.
以下は2つの側面に分けて、第1の側面は主にプロセス向けに対して、この面ではクラスに関与しない.一方,オブジェクト向けに対してstaticのクラスにおける役割を主に説明する.
一、プロセス向け設計におけるstaticキーワード
1、静的グローバル変数
定義:グローバル変数の前にキーワードstaticを付けると、静的グローバル変数として定義されます.
特徴:
A、この変数はグローバルデータ領域にメモリを割り当てる
B、初期化:明示的に初期化しない場合、食事は0に初期化される(自動変数はランダムであり、明示的に初期化しない限り)
C、この変数はソースファイルのみで表示されます.厳密には、定義された場所から本ファイルの終了までです.
Example 1
#include 

using namespace std;

void fun();

static int n;

void main()
{
	n = 20;
	cout<

D、ファイルの役割ドメインで宣言されたconstの定数は、デフォルトでstaticストレージタイプです.
静的変数は、静的ローカル変数を含むグローバルデータ領域にメモリを割り当てます.完全なプログラムの場合、メモリには次のように分散されます.
コード領域
グローバルデータ領域
スタックゾーン
スタック領域
一般にプログラムではnewによって生成された動的データ領域がスタック領域に配置され,関数内部の自動変数がスタック領域に格納される.自動変数は一般的に関数の終了に伴って空間を解放し、静的データ(関数内部の静的ローカル変数でも)はグローバルデータ領域に格納されます.グローバルデータ領域のデータは、関数の終了によって空間を解放するわけではありません.
Example 1の
static int n;次のように変更
int n;//グローバル変数.ファイル内の変数の共有を実現
しかし、静的グローバル変数には次のメリットがあります.
競合することなく、他のファイルで同じ名前の変数を定義できます.
Example 2
FILE 1 
#include 

using namespace std;

void fun();

static int n;

void main()
{
	n = 20;
	cout<

using namespace std;

extern int n;

void fun()
{
	n++;
	cout<

2、静的局所変数
定義:ローカル変数にstaticキーを付けると、静的ローカル変数が定義されます.
FILE 3 
#include 

using namespace std;

void fun();

void main()
{
	fun();
	fun();
	fun();
	
}

void fun()
{
	static int n = 10;
	n++;
	cout<

通常、関数内に変数が定義され、プログラムが文に実行されるたびにローカル変数にスタックメモリが割り当てられますが、プログラムが関数体を終了するにつれて、システムはスタックメモリを回収し、ローカル変数も失効します.しかし、2回の呼び出しの間に変数の値を保存する必要がある場合があります.通常、グローバル変数を定義して実現することが考えられますが、これにより、変数は関数自体に属しなくなり、関数の制御だけでなく、プログラムのメンテナンスに不便をもたらします.
静的局所変数はちょうどこの問題を解決できる.静的ローカル変数は、スタックに保存するのではなく、グローバルデータ領域に保存され、次回の値が付与されるまで、毎回の値は次の呼び出しに維持されます.
特徴:
A、この変数はグローバルデータ領域にメモリを割り当てる
B、初期化:明示的な初期化でなければ、暗黙的に0に初期化され、以降の関数呼び出しは初期化されない.
C.プログラムの実行が終了するまで、常にグローバルデータ領域に存在する.しかし、その役割ドメインは局所的な役割ドメインである.定義された関数または文ブロックが終了すると、その役割ドメインも終了します.
3、静的関数は通常の関数とは異なり、宣言されたファイルでのみ表示され、他のファイルでは使用できません.
Example 4
FILE 4 
#include 

using namespace std;

static void fun();

void main()
{
	fun();
	
}

void fun()
{
    int n = 10;
	n++;
	cout<
静的関数を定義する利点:静的関数は他のファイルでは使用できません.他のファイルで同じ名前の関数を定義でき、競合は発生しません.
二、オブジェクト向けstaticキーワード
1、静的データメンバー
クラス内のデータ・メンバーの宣言にキーワードstaticを追加します.このデータ・メンバーは、クラス内の静的データ・メンバーです.
#include 

using namespace std;

class MyClass
{
public:
	MyClass(int a, int b, int c);
	void fun();
private:
	int a,b,c;
	static int sum;//        
};

 int MyClass::sum = 0;
MyClass::MyClass(int a, int b, int c)
{
	this->a = a;
	this->b = b;
	this->c = c;
	sum += a+b+c;
}

void MyClass::fun()
{
	cout<

以上のプログラムから、静的データ・メンバーには次のような特徴があります.
非静的データ・メンバーの場合、各クラス・オブジェクトには独自のコピーがあります.静的データ・メンバーはクラスのメンバーとして扱われます.このクラスのオブジェクトがどれだけ定義されているかにかかわらず、静的データ・メンバーはプログラム内でコピーが1つしかなく、このタイプのすべてのオブジェクトが共有してアクセスします.すなわち、静的データ・メンバーは、クラスのすべてのオブジェクトに共通しています.このクラスの複数のオブジェクトでは、静的データ・メンバーにはメモリが1回しか割り当てられず、すべてのオブジェクトが共有されます.したがって、静的データ・メンバーの値は各オブジェクトに対して同じであり、その値は更新できます.
静的データ・メンバーはグローバル・データ領域に格納され、静的データ・メンバー定義時にスペースを割り当てるため、クラス宣言では定義できません.クラス外で定義する必要があります.
静的データ・メンバーは、一般的なデータ・メンバーと同様にpublic、private、protectedアクセス・ルールに従います.
静的データ・メンバーは、グローバル・データ領域にメモリを割り当て、このクラスに属するすべてのオブジェクトが共有されるため、特定のクラス・オブジェクトには属しず、クラス・オブジェクトが生成されていない場合に役割ドメインが表示されます.つまり、クラスのインスタンスが生成されていない場合に操作できます.
静的データ・メンバーの初期化は、一般的なデータ・メンバーの初期化とは異なり、初期化フォーマットは次のとおりです.
::=
クラスの静的データ・メンバーには、次の2つのアクセス方法があります.
静的データ・メンバーのアクセス権が許可されている場合、publicメンバーであり、プログラムでは、上記のフォーマットで静的データ・メンバーを参照することができる.
静的データ・メンバーは、主に各オブジェクトに同じ属性がある場合に使用されます.たとえば、1つの預金クラスについては、インスタンスごとに利息が同じであるため、利息を預金クラスの静的データメンバーに設定することができます.これには、複数の預金クラス・オブジェクトを定義しても、利息データ・メンバーがグローバル・データ領域に割り当てられたメモリを共有するため、ストレージ・スペースが節約されるという2つのメリットがあります.二つ目は、金利を変更する必要がある場合、一度変更すれば、すべての預金類の対象の金利がすべて変更されます.
静的データ・メンバーの使用には、グローバル変数と比較して2つの利点があります.
(1)静的データメンバーはプログラムのグローバル名前空間に入っていないため、プログラム内の他のグローバル名前と衝突する可能性はない.
(2)情報隠蔽が可能である.静的データ・メンバーはprivateメンバーを使用できますが、グローバル変数は使用できません.
2、静的メンバー関数
静的データ・メンバーと同様に、クラスの特定のオブジェクトにサービスするのではなく、クラスのすべてのサービスに対する静的メンバー関数を作成することもできます.静的メンバー関数は、静的データメンバーと同様にクラスの内部で実装され、クラス定義の一部に属します.通常のメンバー関数は、通常のメンバー関数が常に特定のクラスの特定のオブジェクトに属するため、クラスのオブジェクト自体を指すthisポインタを非表示にします.通常、thisポインタはデフォルトですが、通常の関数と比較して、静的メンバー関数は任意のオブジェクトに関連付けられていないため、thisポインタはありません.この意味では、クラスオブジェクトに属する非静的データメンバーにも非静的メンバー関数にもアクセスできません.残りの静的メンバー関数のみを呼び出すことができます.
Example 6
#include 

using namespace std;

class MyClass
{
public:
	MyClass(int a, int b, int c);
	static void fun();
private:
	int a,b,c;
	static int sum;//        
};

 int MyClass::sum = 0;
MyClass::MyClass(int a, int b, int c)
{
	this->a = a;
	this->b = b;
	this->c = c;
	sum += a+b+c;
}

void MyClass::fun()
{
	cout<

静的メンバー関数については、次の点をまとめることができます.
(1)クラス外に現れる関数はキーワードstaticを指定できない.
(2)静的メンバー間で相互にアクセスすることができ、静的メンバー関数から静的データメンバーへのアクセスと静的メンバー関数へのアクセスを含む.
(3)非静的メンバー関数は、静的メンバー関数および静的データメンバーに任意にアクセスすることができる.
(4)静的メンバー関数は、非静的メンバー関数および非静的データメンバーにアクセスできない.
(5)thisポインタの追加オーバーヘッドがないため、静的メンバー関数はクラスのグローバル関数に比べて速度が少し増加する.
(6)スタティックメンバー関数を呼び出し,オペレータ(.)にメンバーでアクセスできる.および(->は、クラスのオブジェクトまたはクラスオブジェクトを指す静的メンバー関数を呼び出します.