インスタンスメンバーと静的メンバー
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 27/104。
これまでに作成したすべてのメンバー変数は、特定のオブジェクトに属しています。2つのPlayerオブジェクトを作成すると、それぞれが独自のnameとhealthを持ちます。これらはインスタンスメンバーと呼ばれます。つまり、クラスの各インスタンスごとに個別に存在します。
しかし、すべてのオブジェクト間で共有されるデータが必要な場合はどうでしょうか? たとえば、プレイヤーが合計で何人存在するかを追跡する場合です。
ここでstatic メンバーの出番です。static メンバーはクラス自体に属し、特定のオブジェクトには属しません。
class Player {
std::string name; // インスタンスメンバー - 各プレイヤーが独自に持つ
int health; // インスタンスメンバー
static int playerCount; // 静的メンバー - すべてのプレイヤーで共有
public:
Player(std::string n) : name(n), health(100) {
playerCount++; // プレイヤーが作成されたときにインクリメント
}
~Player() {
playerCount--; // プレイヤーが破棄されたときにデクリメント
}
};主な違いは、インスタンスメンバーにはオブジェクトを介してアクセスするのに対し、staticメンバーにはクラス名自体を介してアクセスできる点です。インスタンスメンバーは「オブジェクトごとに1つ」、staticメンバーは「classごとに1つ」と考えてください。
| インスタンスメンバー | 静的メンバー |
|---|---|
| 各オブジェクトに固有 | すべてのオブジェクトで共有 |
| オブジェクトの作成時に作成される | オブジェクトが作成される前に存在する |
オブジェクト経由でアクセス: player.health | クラス経由でアクセス: Player::playerCount |
静的メンバーは、カウンター、設定値、または個々のオブジェクトではなく論理的にクラスに属するあらゆるデータに役立ちます。
チャレンジ
簡単インスタンスメンバーと static メンバーを使用して、個々の商品の詳細と在庫全体の統計情報の両方を追跡する商品在庫システムを構築しましょう。
コードを整理するために、次の2つのファイルを作成します。
Product.h: 個々の商品を管理しながら、在庫全体のデータも追跡するProductクラスを Define します。クラスには次の要素を含めます。- インスタンスメンバー:
name(string)とprice(double)。各商品に固有 - 現在存在する商品の数を数える static メンバー
totalProducts - すべての商品の価格の合計を追跡する static メンバー
totalValue - name と price を受け取り、インスタンスメンバーを初期化し、両方の static カウンターを更新するコンストラクター(count を Increment し、price を合計値に add する)
- 商品が削除されたときに static カウンターを更新するデストラクター(count を Decrement し、price を合計値から引く)
- 次の format の文字列を返す
getInfo()メソッド:"<name>: $<price>" - 次の文字列を返す static メソッド
getInventoryStats():"Products: <count>, Total Value: $<value>"
- インスタンスメンバー:
main.cpp: static メンバーがすべてのオブジェクト間で共有される一方、インスタンスメンバーは固有のままであることを示します。2つの商品名とそれぞれの価格を入力(name1、price1、name2、price2: それぞれ別の行)から読み取り、その後、次の処理を行います。- クラス名を使用して初期在庫統計を出力します:
Product::getInventoryStats() - curly braces を使ってスコープブロックを作成し、その中で最初の商品名と価格を使って
Productを作成します。その情報と current の在庫統計を出力します。 - ブロックが ends した後(最初の商品が破棄された後)、
"After first scope:"に続けて在庫統計を出力します。 - 2番目の商品名と価格を使って another
Productを作成します。その情報と在庫統計を出力します。 - name
"Bonus"、price5.00の3番目のProductを作成します。final の在庫統計を出力します。
- クラス名を使用して初期在庫統計を出力します:
static メンバーは、クラス定義の後にヘッダーファイル内でクラスの外部に Declare することを Remember してください。<iomanip> の std::fixed と std::setprecision(2) を使用して、価格を小数点以下2桁で Format します。
#include "Product.h" を使用して、ヘッダーファイルを main.cpp に Include します。
自分で試してみよう
#include <iostream>
#include <string>
#include "Product.h"
using namespace std;
int main() {
// 入力を読み取る
string name1;
double price1;
string name2;
double price2;
getline(cin, name1);
cin >> price1;
cin.ignore();
getline(cin, name2);
cin >> price2;
// TODO: Product::getInventoryStats() を使用して初期インベントリ統計を出力する
// TODO: 波括弧でスコープブロックを作成する
// ブロック内:
// - name1 と price1 で Product を作成する
// - getInfo() を使用してその情報を出力する
// - 現在のインベントリ統計を出力する
// TODO: After the block ends, print "After first scope:"
// 次にインベントリ統計を出力する
// TODO: name2 と price2 でもう1つの Product を作成する
// その情報とインベントリ統計を出力する
// TODO: 名前 "Bonus" と価格 5.00 で3つ目の Product を作成する
// 最終的なインベントリ統計を出力する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタパラメータ付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ徹底解説Rule of Three / Five / Zero復習 - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () の演算子オーバーロード型変換演算子復習 - Matrixクラス自分で練習してみよう: C++オンラインコンパイラ