C++ で静的キーワードを使用する

胡金庫 2023年10月12日
  1. C++ で static キーワードを使用して静的期間の変数を宣言する
  2. C++ で static キーワードを使用してクラスの静的メンバーを宣言する
C++ で静的キーワードを使用する

このガイドでは、C++ で static キーワードを使用する方法のいくつかの方法について説明します。

C++ で static キーワードを使用して静的期間の変数を宣言する

static キーワードを使用して、静的期間のローカル変数を宣言できます。名前が示すように、静的期間のローカル変数は、変数が宣言されているブロックがスコープ外になった後でも、その値がメモリ内でアクティブなままであることを意味します。

基本的に、これらのローカル変数は、定義されている関数呼び出しの間に値を保存できます。incrementCount 関数には、0 の値で初期化される count という変数があることに注意してください。count 属性は、プログラムが終了するまでアクティブなメモリ領域に割り当てられます。したがって、incrementCount を呼び出すたびに、指定された整数に 1つの単位が追加されます。

#include <iostream>

using std::cout;
using std::endl;

int incrementCount() {
  static int count = 0;
  return ++count;
}

int main() {
  for (int i = 0; i < 20; ++i) {
    if (i % 2 == 0) incrementCount();
  }
  cout << incrementCount() - 1 << endl;

  return EXIT_SUCCESS;
}

出力:

10

C++ で static キーワードを使用してクラスの静的メンバーを宣言する

一方、static キーワードは、クラスの静的データメンバーを宣言するために使用されます。これらのメンバーは、クラスの特定のインスタンスではなく、クラスタイプ自体に関連付けられています。したがって、特定のクラスに静的データメンバーを定義すると、このクラスタイプのすべてのインスタンスは、データメンバーに対して同じ値を持ちます。プライベートメンバーを持つのとは異なり、前者はメモリに単一のコピーを持ちます。後者の機能により、静的データメンバーはクラスメモリフットプリントの観点から効率的になります。

静的データメンバーは、通常のデータメンバーとは異なる方法で定義および初期化されます。static メンバーは、クラス内で宣言し、関連するソースファイルのクラス外で定義する必要があります。static キーワードは、クラス内の宣言でのみ使用されます。コンストラクターで初期化できる static データメンバーはなく、const 整数型でない限り、クラス本体内で初期化することはできません。後者のタイプは、初期値を指定せずにクラス本体の外部で定義する必要があります。次の例は、文字列リテラルで初期化され、後で setNewName 関数で変更される static データメンバーname の簡単な使用法を示しています。

#include <iostream>
#include <string>
#include <utility>

using std::cin;
using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  static string name;
  string nickname;

 public:
  explicit MyClass1(string n) : nickname(std::move(n)){};

  static string getName() { return name; }
  static void setNewName(std::basic_string<char> s) { name = std::move(s); }
  string getNickname() { return nickname; }

  ~MyClass1() = default;
};

string MyClass1::name = "Static name";

int main() {
  MyClass1 m1(string("April"));
  MyClass1 m2(string("Maude"));

  cout << MyClass1::getName() << endl;
  MyClass1::setNewName("New name");
  cout << MyClass1::getName() << endl;

  return EXIT_SUCCESS;
}

出力:

Static name
New name

あるいは、クラスには、どのオブジェクトにもバインドされていない static 関数メンバーが含まれている可能性があるため、本体で this オブジェクトを参照することはできません。一般に、これらの関数は、次のサンプルプログラムに示すように、静的データメンバーのように個別の宣言と定義を持つ必要はありません。それでも、ほとんどの現代的なスタイルガイドでは、通常、プログラマーが 2つを切り離す必要があります。

#include <iostream>
#include <string>
#include <utility>

using std::cin;
using std::cout;
using std::endl;
using std::string;

class MyClass1 {
 private:
  static string name;
  string nickname;

 public:
  explicit MyClass1(string n) : nickname(std::move(n)){};

  static string getName() { return name; }
  static void setNewName(std::basic_string<char> s) { name = std::move(s); }
  string getNickname() { return nickname; }

  static bool compareStrings(const std::basic_string<char>& s1,
                             const std::basic_string<char>& s2) {
    if (s1 == s2)
      return true;
    else
      return false;
  }

  ~MyClass1() = default;
};

string MyClass1::name = "Static name";

int main() {
  MyClass1 m1(string("April"));
  MyClass1 m2(string("Maude"));

  MyClass1::compareStrings(m1.getNickname(), m2.getNickname())
      ? cout << "strings are equal" << endl
      : cout << "strings are not equal" << endl;

  MyClass1::compareStrings(MyClass1::getName(), MyClass1::getName())
      ? cout << "strings are equal" << endl
      : cout << "strings are not equal" << endl;

  return EXIT_SUCCESS;
}

出力:

strings are not equal
strings are equal
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Static