モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

静的staticメンバ (C++をもう一度)

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2014/12/14
最終更新最終更新
2017/04/28
記事区分記事区分
一般公開

目次

    低レイヤーのプログラミングとOS開発が趣味。C言語を使っています。

    0
    ステッカーを贈るとは?

    静的メンバ変数

    sub.h

    #ifndef SUB_H_
    #define SUB_H_
    
    class MyClass {
    public:
        MyClass(int intval);
    
    public:
        void Show() const;
    
    private:
        static int m_intval; // 静的メンバ変数
    };
    
    #endif // #ifndef SUB_H_
    

    sub.cpp

    #include <iostream>
    #include "sub.h"
    using namespace std;
    
    int MyClass::m_intval; // 実体を生成 <*1>
    // int MyClass::m_intval = 0; // として初期化可能
    
    MyClass::MyClass(int intval) {
        m_intval = intval; // 代入
    }
    
    // 初期化↓はエラーです。初期化は実体を生成するタイミング <*1> でのみ可能です。
    // MyClass::MyClass(int intval) :
    //     m_intval(intval)
    // {
    // }
    
    void MyClass::Show() const {
        cout << m_intval << endl;
    }
    

    main.cpp

    #include <iostream>
    #include "sub.h"
    using namespace std;
    
    int main() {
        MyClass obj_1(1);
        MyClass obj_2(2);
        obj_1.Show(); //=> 2 (← 1ではないのがポイントですね)
        obj_2.Show(); //=> 2
        return 0;
    }
    

    コンパイル方法例

    g++ -Wall -o main.o -c main.cpp
    g++ -Wall -o sub.o -c sub.cpp
    g++ -Wall -o main main.o sub.o
    

    静的メンバ関数

    クラスにはオブジェクト実体のアドレスを必要としないメンバ関数を登録できます。このメンバ関数を特に静的メンバ関数とよびます。実体がなくても実行できますが、実体のアドレスが渡されていないため静的でないメンバにはアクセスできません。

    #include <iostream>
    using namespace std;
    
    class MyClass {
    public:
        static void Show(); // 静的メンバ関数
    
    private:
        static int m_intval;
    };
    
    int MyClass::m_intval = 1;
    
    void MyClass::Show() {
        cout << m_intval << endl;
    }
    
    int main() {
        MyClass::Show(); //=> 1
        return 0;
    }
    

    静的メンバ関数を利用すると、シングルトンパターンをC++でも実装できます。

    #include <iostream>
    using namespace std;
    
    class MyClass {
    private:
        static MyClass* singleton; // 唯一のインスタンスを保持
    
    private:
        MyClass(); // new できなくする
        MyClass(const MyClass& other); // コピーコンストラクタも private にします
    
    public:
        static MyClass* GetInstance();
    
    public:
        void Greet();
    };
    
    MyClass* MyClass::singleton = new MyClass();
    
    MyClass::MyClass() {
    }
    
    MyClass::MyClass(const MyClass& other) {
    }
    
    MyClass* MyClass::GetInstance() {
        return singleton;
    }
    
    void MyClass::Greet() {
        cout << "MyClass::Greet" << endl;
    }
    
    int main() {
        MyClass* singleton = MyClass::GetInstance();
        singleton->Greet();
        return 0;
    }
    

    静的メンバ定数

    クラスの静的メンバ変数に const を付与すると、静的 static かつ値の不変なメンバを定義できます。static だけの場合と同様にコンパイル時に静的にメモリ領域が確保され、実行中はアドレスが一定です。グローバル変数に const を付与すると内部リンケージを持たせることができますが、この場合の static と const の関係とは状況が異なりますので混同しないようにしてください。

    #include <iostream>
    using namespace std;
    
    class MyClass {
    public:
        static const int SIZE = 8;
    
    private:
        int m_intarr[SIZE]; // 静的かつ定数なので配列サイズ指定に使用できる。
    };
    
    int main() {
        MyClass obj;
        cout << MyClass::SIZE << endl; //=> 8
        return 0;
    }
    

    メンバ定数 (参考)

    静的メンバではありませんが、メンバ定数というものも定義できます。一般に const 定数は代入はできませんが初期化はできます。

    #include <iostream>
    using namespace std;
    
    class MyClass {
    public:
        MyClass(int intval);
    
    public:
        void Show() const;
    
    private:
        const int m_intval;
    };
    
    MyClass::MyClass(int intval) :
        m_intval(intval) // 初期化はできる
    {
        // m_intval = intval * 2; // 代入はできない
    }
    
    void MyClass::Show() const {
        cout << m_intval << endl;
    }
    
    int main() {
        MyClass obj(1);
        obj.Show(); //=> 1
        return 0;
    }
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    低レイヤーのプログラミングとOS開発が趣味。C言語を使っています。

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      関連記事