marunomaruno-memo

marunomaruno-memo

[C++] 自分自身のインスタンスを定数で持つクラス

2012年10月08日 | Android
自分自身のインスタンスを定数で持つクラス
================================================================================

自分自身のインスタンスを定数で持つクラスのサンプル。

メンバー変数は、たんに int 型の値を持っているだけ。
コンストラクターをすべて private にすれば、他から直接インスタンスを生成できない
ようにすることもできる。


□ Item.h
---
#ifndef ITEM_H_
#define ITEM_H_

#include <iostream>

class Item {
public:
    static const Item* ITEM1;    // (1)
    static const Item* ITEM2;    // (1)

    static const Item* ITEM_LIST[];    // (2)
    static const int ITEM_LIST_SIZE;    // (3)

private:
    int value;

public:
    Item();
    Item(int value);
    virtual ~Item();

    int getValue() const;
};

#endif /* ITEM_H_ */
---

(1) 自分自身のオブジェクトの定数の宣言

    static const Item* ITEM1;    // (1)
    static const Item* ITEM2;    // (1)

(2)(3) オブジェクト定数配列の宣言とその要素数の宣言

オブジェクト定数を配列で持っていることで、使い勝手が向上するかもしれない。
そのときの要素数も持たせておく。

    static const Item* ITEM_LIST[];    // (2)
    static const int ITEM_LIST_SIZE;    // (3)

ここで、ITEM_LIST_SIZE は int 型だから、
    static const int ITEM_LIST_SIZE = sizeof(Item::ITEM_LIST)
                / sizeof(Item::ITEM_LIST[0]);
とすると、つぎのメッセージでコンパイルエラーとなる。
    invalid application of `sizeof' to incomplete type `const Item*[]' 
この時点では、ITEM_LIST の要素が確定していないため。


□ Item.cpp
---
#include <iostream>
#include <cassert>
#include "Item.h"

const Item* Item::ITEM1 = new Item(10);    // (1)
const Item* Item::ITEM2 = new Item(20);    // (1)

const Item* Item::ITEM_LIST[] = { ITEM1, ITEM2 };    // (2)
const int Item::ITEM_LIST_SIZE = sizeof(Item::ITEM_LIST)
        / sizeof(Item::ITEM_LIST[0]);    // (3)

Item::Item() {
    assert(true);
}

Item::Item(int value) :
        value(value) {
    assert(true);
}

Item::~Item() {
    assert(true);
}

int Item::getValue() const {
    return value;
}
---

(1) 自分自身のオブジェクトの定数の定義

const Item* Item::ITEM1 = new Item(10);    // (1)
const Item* Item::ITEM2 = new Item(20);    // (1)


(2) オブジェクト定数配列の定義

const Item* Item::ITEM_LIST[] = { ITEM1, ITEM2 };    // (2)


(3) オブジェクト定数配列の要素数の定義

const int Item::ITEM_LIST_SIZE = sizeof(Item::ITEM_LIST)
        / sizeof(Item::ITEM_LIST[0]);    // (3)


□ ItemTest.cpp
---
#include <iostream>
using namespace std;

#include "Item.h"

int main() {
    cout << Item::ITEM1->getValue() << endl;
    cout << Item::ITEM2->getValue() << endl;

    for (int i = 0; i < Item::ITEM_LIST_SIZE; ++i) {
        cout << Item::ITEM_LIST[i]->getValue() << endl;
    }

    Item item;
    cout << item.getValue() << endl;

    Item item2(30);
    cout << item2.getValue() << endl;

    return 0;
}
---


□ 実行結果
---
10
20
10
20
0
30
---

                                                                            以上