【C++基礎学習】C++静的メンバー関数と変数について


コード1:
class Point{
public:
	void output()
	{
	}
	static void init()
	{
	}
};
int main()
{
	Point pt;
	pt.init();
	pt.output();
}
コード2:
class Point{
public:
	void output()
	{
	}
	static void init()
	{
	}
};
int main()
{
	Point::init();
	Point::output();//  
}

2つのコードコンパイルが実行され、コードが成功すると、コード2がエラーを報告します.エラーメッセージ:
test1.cpp(16):errorC 2352:「Point::output」:非静的メンバー関数の不正呼び出し.
エラーメッセージ:非静的メンバー関数Point::outputが不正に呼び出されました.しかし、なぜinit関数の呼び出しが間違っていないのでしょうか.この関数は静的関数です.静的メンバー関数と静的メンバー変数はクラス自体に属し、クラスがロードされると空間が割り当てられるため、クラス名::関数名またはクラス名:変数名でアクセスできます.静的メンバー関数や非静的メンバー変数ではなく、オブジェクトのメソッドとデータに属します.つまり、クラスのオブジェクトを最初に生成し、クラスのオブジェクトで参照する必要があります.
コード3:
#include <iostream>
using namespace std;

class Point{
public:
	void output()
	{
	}
	static void init()
	{
		x = 0;
		y = 0;
	}
private:
	int x,y;
};
int main()
{
	Point::init();
	//Point::output();//  
}
実行エラー:
1>e:学習プログラム練習test 1test 1test 1.cpp(11):error C 2597:非静的メンバー「Point::x」への不正参照
1>e:学習プログラム練習test 1test 1test 1.cpp(12):error C 2597:非静的メンバー「Point::y」への不正参照
静的メンバー関数でPointオブジェクトのxおよびyデータメンバーを不正に参照します.Initは静的関数であるため,ある特定のオブジェクトに属さず,つまりPointクラスのいずれかの特定のオブジェクトがまだ生成されていない場合には,その関数は既にプログラムのコード領域に存在する.ただし、Pointクラスのデータメンバーxとyにはメモリ領域が割り当てられていないため、init関数で値を割り当てる操作は失敗します.すなわち、非静的メンバー関数および非静的メンバー変数を含む、静的メンバー関数では非静的メンバーを呼び出すことはできません.静的メンバー関数は、静的メンバー変数にのみアクセスできます.
上記のコードのx,yに対する付与操作を非静的関数に置くと成功する.ただし、非静的メンバー関数では静的メンバー関数を呼び出すことができます.
上記のコードでは、Pointクラスのデータメンバーxとyの定義の前にstatic修飾子を付けて、静的メンバー変数にすることができます.
staticintx,y;
コンパイル実行、プログラムエラー.エラーメッセージ:
1>test1.obj:error LNK 2001:解析できない外部シンボル「private:static int Point::y」(?y@Point@@0HA)
1>test1.obj:error LNK 2001:解析できない外部シンボル「private:static int Point::x」(?x@Point@@0HA)
これはリンク時に発生したエラーです.エラーの原因は、静的メンバー変数の初期化が必要であり、クラスの定義以外でこの操作を行う必要があるためです.Pointクラスの定義に加えて、次の2つの初期化文を追加します.
intPoint::x = 0;
intPoint::y = 0;

は正常に実行されました.