よろしくお願いします。C++の勉強してて、
こんな事出来るのかな?って言う疑問が沸いたので、
質問させてください。
以下のようなクラスを作りました。
class CTestB;
class CTestA {
friend CTestB;
public:
void func();
:
private:
CTestA(int n);
};
------------------------
class CTestB {
public:
CTestB();
void func();
:
private:
map<int, CTestA*> map_;
};
CTestB::CTestB() {
for (int i = 0; i < 10; i++) {
map_.insert(make_pair(i, new CTestA(i)));
}
}
CTestAクラスは単独では生成不可でCTestBからのみ生成出来るものとして、
CTestBのコンストラクタで、CTestAのインスタンスを複数生成して、
map_に割り当てをしたいのですが、このmapをプログラム内で1つしか
存在しないようにしたいんです。
CTestBをいくつ生成しようが、mapは常に同じものを指し示す様にしたい
のです。
mapの宣言にstaticとしたのですが、リンク時に外部参照が未解決と
出てしまい、対応方法が良くわかりません。
また、仮に上手く出来たとして、生成したCTestAのインスタンスは
どこで解放してやるべきなのでしょうか?
CTestBのデストラクタで解放してしまったら、複数CTestBを生成した
場合に最初のCTestBをdeleteしたら、以降のdeleteで異常終了すると
推測されるのですが・・・。(mapに登録されてる個数を判定する・・・?)
特に何をするプログラムではないのですが、CTestAを直接触れさせずに
別のクラスで生成させると言う手法は良くあると思うのですが。
単純な事かも知れませんが、よろしくお願いします。
シングルトンパターンと言うのがオブジェクト指向のデザインパターンに
あったと思うので調べて見てはどうでしょうか。
クラスのstaticなメンバー変数に関しては記述方法がちゃんと有りますので
調べて見た方が良いです。ただヘッダーファイルのクラス宣言の中で
staticで宣言すれば良いと言うわけにはいきませんから確認してみてください。
基本的にstaticな変数はそのプロセスが終了する時に開放されると思います。
従ってmapのインスタンスが開放されるときに必要なインスタンスがきちんと
開放されるように組んでおく必要があると思います。
C++言語の文法とクラスの概念(派生やら仮想関数やら)を理解できたら
オブジェクト指向設計のデザインパターンと言うのを勉強すると
色々なケースに対応する時の典型的な処理方法と言うのがわかってくると
思います。但し、デザインパターンに振り回されてしまわないように
注意する必要はあると思います。
PATIOさんありがとうございます。
レスの内容から察するに、私のやりたい事は
そういったことは可能と言うことですよね。
是非調べてやってみます。
ありがとうございました。
自分のは補足です。一般に
class N{ static M m;};
の場合、N.cpp 内などで
M N::m;
のように実体を記述します。mはmain()のスコープ外ですので
Mのコンストラクタはmain()より前に、デストラクタはmain()
スコープの後で実行され、従ってmの生成破棄のタイミングを
コードで制御することはできません。今一ですよねぇ。
似たような唯一オブジェクトの寿命等をコントロールする方法として
PATIO さんの発言にあるシングルトンパターンがなどがあり、
もちっと賢い仕組みになってるわけです。
んが、機能が充実するに比例して、直感的に理解できるコードでは
なくなり、今度はこの点で今一になります。
少なくとも自分には少し難解でした。
> スコープの後で実行され、従ってmの生成破棄のタイミングを
> コードで制御することはできません。今一ですよねぇ。
main終了時にメモリリーク扱いにされたりしますね。
それが嫌で↓こんな風にポインタにして、main終了時に明示的にdeleteしたりもします。
class N {
static M *m;
public:
void deleteM() { delete m; }
};