Cpp クラス 静的メンバ変数

提供:yonewiki
2022年9月26日 (月) 11:15時点におけるYo-net (トーク | 投稿記録)による版 (ページの作成:「C++に戻る <table class="mbox-small" style="border:1px solid #aaa; background-color:#f9f9f9; width:22em;" id="RealTitleBanner"> <tr> <td style="width:1px;"></td> <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C++(Cpp) クラス 静的メンバ変数</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなっ…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

C++に戻る


本来の表記は「C++(Cpp) クラス 静的メンバ変数」です。この記事に付けられた題名はテンプレート:記事名の制約から不正確なものとなっています。

※このページではC++にのみ存在する機能として、記事タイトルがC++ クラス 静的メンバ変数になっています。

静的メンバ変数

静的変数は関数をまたいでも使えた変数でした。静的メンバ変数はクラスの中に宣言される変数で、利用することを宣言すれば、クラスを変数化したり、ポインタ変数によって実体化することなく利用できる変数となります(この2種類の変数を含めてオブジェクトと表現したいと思います。自分はプログラム中では通常の変数は_objとサフィックスをつけて明示したり、ポインタによるインスタンスは_instanceや_iのようなサフィックスをつけたりして区別することがあります。)。クラスのオブジェクトを生成しなくても使えるという利点がある反面、逆に言えば複数のオブジェクトを作っても一つしか使えないということです。これはクラスの中にある唯一の変数となることからグローバル変数とは違った独立性を保持すると考えれば、そういった使い方をするためのものだと考えるべきです。


静的メンバ変数はプログラムの中でクラスが複数実体化されようと、宣言さえすれば使える唯一の変数であるということになります。


また静的メンバ変数は、プロトタイプ宣言が終わった後のスコープの外側で実体化を定義できる変数になります。ここのサンプルでは、標準の型を使った変数ですが、クラスそのものや、構造体、共有体、列挙型のようなユーザが定義する型でも定義できます。


静的メンバ変数を実体化するタイミングは通常クラスならクラスのヘッダファイルと対になるプログラムファイルに記述します。例えば、CStaticMemberVar001というクラスの中にある静的メンバ変数ならStaticMemberVar001.hファイルで静的メンバ変数を定義し、StaticMemberVar001.cppのスコープの外側で実体化をします。もちろんsample_main.cppのようなプログラムファイルのスコープの外側で実体化しても良いですが、あまりクラスを使う側に実体化を任せるということはないと思いますし、ややこしくなるので、あまりそういうことはしないのではないかと思います。


では実際に使ってみます。


StaticMemberVar001.h

#pragma once

class CStaticMemberVar001
{
private:
  static int m_nValue_static;   //★1.静的メンバ変数宣言 アクセス指定子 プライベート
public:
  static int mpub_nValue_static;//★2.静的メンバ変数宣言 アクセス指定子 パブリック

  CStaticMemberVar001(void);
  ~CStaticMemberVar001(void);
};

StaticMemberVar001.cpp

#include "stdafx.h"
#include "StaticMemberVar001.h"

int CStaticMemberVar001::m_nValue_static    = 0;//★3.実体化 アクセス指定子プライベート
int CStaticMemberVar001::mpub_nValue_static = 0;//★4.実体化 アクセス指定子パブリック

CStaticMemberVar001::CStaticMemberVar001(void)
{
  printf("CStaticMemberVar001::m_nValue_static = %d\n",m_nValue_static);//★5.静的メンバ変数利用 プライベート
  m_nValue_static = 100;
  printf("CStaticMemberVar001::m_nValue_static = %d\n",m_nValue_static);
}


CStaticMemberVar001::~CStaticMemberVar001(void)
{
}

メインプログラムは以下のようなものにしました。


sample_main.cpp

#include "stdafx.h"
#include "StaticMemberVar001.h"

int _tmain(int argc, _TCHAR* argv[])
{
  //★6.静的メンバ変数利用 パブリック
  printf("CStaticMemberVar001::mpub_nValue_static = %d\n",CStaticMemberVar001::mpub_nValue_static);
  CStaticMemberVar001::mpub_nValue_static = 200;
  //CStaticMemberVar001::m_nValue_static = 1000;//★7.静的メンバ変数利用 プライベートへのアクセスは駄目。
  printf("CStaticMemberVar001::mpub_nValue_static = %d\n",CStaticMemberVar001::mpub_nValue_static);

  CStaticMemberVar001*  CStaticMemberVar001_Instance = new  CStaticMemberVar001;

  return 0;
}

出力結果

CStaticMemberVar001::mpub_nValue_static = 0
CStaticMemberVar001::mpub_nValue_static = 200
CStaticMemberVar001::m_nValue_static = 0
CStaticMemberVar001::m_nValue_static = 100

★1.と★2.部分で静的メンバ変数を定義しました。★3.★4.部分で実体化しています。クラスのプログラミング部分であるStaticMemberVar001.cppのスコープ外で実体化しています。そして★6.ではメイン関数からパブリックとしてアクセス指定子を割り振った静的メンバ変数の呼び出しをしています。★7.の部分からはプライベートな静的メンバ変数にはアクセスできません。アクセス指定子は静的なメンバ変数に対しても通常のメンバ変数同様の効力を持ちます。★5.のようにクラス内からであれば、名前スコープ解決演算子も必要なく、プライベートな静的メンバ変数にアクセスできます。実体化した変数に対して、アロー演算子やドットによる選択演算子を使って呼び出しすることもできますが、複数の実体化した変数であってもすべて一つの変数ですので、同じものを呼び出していることになります。


C++に戻る