シングルトンパターンを使用した場合のデストラクタ呼び出し

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
yow

シングルトンパターンを使用した場合のデストラクタ呼び出し

#1

投稿記事 by yow » 10年前

はじめまして。現在c,c++を用いてSTGを作成中なのですが、
件名の通り、シングルトンパターンを用いたクラスのインスタンスを
上手く終わらせることができず困っております。
具体的には以下のような関数を用いています。
static CONTROL& GetInstance(){
static CONTROL control;
return control;
}
これを他クラスから呼び出してCONTROLクラスにアクセスしているのですが、
CONTROLクラスのデストラクタを呼び出すことが出来ません。
何か良い方法がありましたらご教授よろしくお願いします。

アバター
馬場自由
記事: 15
登録日時: 11年前

Re: シングルトンパターンを使用した場合のデストラクタ呼び出し

#2

投稿記事 by 馬場自由 » 10年前

プログラム終了時にデストラクタが呼ばれると思いますが、それだとダメですか?
シングルトンはその性質上任意にインスタンスを破棄できないので、デストラクタに相当する処理を
関数として定義し、適宜呼ぶ必要があると思います。

yow

Re: シングルトンパターンを使用した場合のデストラクタ呼び出し

#3

投稿記事 by yow » 10年前

回答頂きありがとうございます。
なるほど、インスタンスを任意に破棄できないのですね。
ということは、コンストラクタもインスタンス生成時に一度呼ばれるだけで
その後は任意に呼ぶことはできないということでしょうか?
だとすると、コンストラクタとデストラクタに変わって初期化、終了処理を
行うような関数をそれぞれ作ればよいのでしょうか?

アバター
へにっくす
記事: 634
登録日時: 12年前
住所: 東京都

Re: シングルトンパターンを使用した場合のデストラクタ呼び出し

#4

投稿記事 by へにっくす » 10年前

yow さんが書きました:コンストラクタとデストラクタに変わって初期化、終了処理を
行うような関数をそれぞれ作ればよいのでしょうか?
そういうことになるが、ちょっと考えれば分かることなんでないかい?
Singletonパターン - Wikipedia
別に初期化処理=コンストラクタ、終了処理=デストラクタにこだわる必要はないと思うんだけど?
オフトピック
個人的には、一回だけ呼ぶならともかく、そう何度も初期化/終了処理を呼ぶようなクラスは、シングルトンパターンにするのは変かなと思うけど。
written by へにっくす

アバター
GRAM
記事: 164
登録日時: 13年前
住所: 大阪

Re: シングルトンパターンを使用した場合のデストラクタ呼び出し

#5

投稿記事 by GRAM » 10年前

yow さんが書きました:その後は任意に呼ぶことはできないということでしょうか?
だとすると、コンストラクタとデストラクタに変わって初期化、終了処理を
行うような関数をそれぞれ作ればよいのでしょうか?
そういうことは別にないと思いますよ

コード:

static CONTROL* control_; //(nullptrで初期化)

static CONTROL& GetInstance(){
	if( control_ == nullptr )
	{
		control_ = new CONTROL();
	}
	return *control_;
}

static void Finalize()
{
	delete control_;
	control_ = nullptr;
}
のようなことをすればできなくはないと思いますが…
(それを望むのであれば。ただしプログラムの終了時にdeleteしてほしいのであればもうちょっと工夫がいると思います)

yow

Re: シングルトンパターンを使用した場合のデストラクタ呼び出し

#6

投稿記事 by yow » 10年前

へにっくす さんが書きました:別に初期化処理=コンストラクタ、終了処理=デストラクタにこだわる必要はないと思うんだけど?
なるほど、別に拘る必要はなかったんですね。すみません、まだプログラミングを始めたばかりでしてどうも固定観念が働いて
おりました。
GRAM さんが書きました:そういうことは別にないと思いますよ
コードを貼って頂きありがとうございました。ひとまず、このコードを使用して上手く動作するか確認してみます。

お二方ともご教授ありがとうございました。

アバター
GRAM
記事: 164
登録日時: 13年前
住所: 大阪

Re: シングルトンパターンを使用した場合のデストラクタ呼び出し

#7

投稿記事 by GRAM » 10年前

コードを貼って頂きありがとうございました。ひとまず、このコードを使用して上手く動作するか確認してみます。
お二方ともご教授ありがとうございました。
あの表現で伝わりましたか自信がないので強調しておきますが、
このコードをそのまま使う場合プログラムの終了直前にFinalize関数を呼び出さないと、
Controlクラスのデストラクタが呼び出されません。
例えばControlクラスのデストラクタで何らかしら絶対動作に必要な処理が行われるのなら、
必ずFinalize関数を呼び出すように徹底しなくてはならないと思います。
(解決するためにはControlのポインタをスマートポインタにすればよいと思います)

また直接的な問題ではないのですが、このコードの場合誰かがControlのインスタンスの参照なりポインタなりを
(Instanceの戻り値を何らかの形で)保持してしまうと、ほかの誰かがControlをFinalizeしてしまった場合それを知る術がありません。
つまりControlのインスタンスを何らかの形で(一時的にでも)保持する場合は注意してください。
(この問題の一応の解決策もないことはないですが、とりあえずはそういう問題があるということをお伝えしておきます)

これら問題はへにっくすさんのおっしゃる方法であれば、あまり問題にはならないと思います。
(Initialize関数が呼ばれているかどうかをチェックする機構を設ければよいだけなので。また終了処理はデストラクタ呼び出せばよい)

私がしたのは、コンストラクタとデストラクタを呼び出すのが不可能ではないという話であり、
そうするのが適切かどうかという話ではありませんのでご了承ください。
(実際問題として、私のコードの関数をそのままにControlクラスの実装を変えるだけで、へにっくすさんの手法をとることも容易です。
私が思うに、この目的を達成する手段はたくさんあると思います。)

yow

Re: シングルトンパターンを使用した場合のデストラクタ呼び出し

#8

投稿記事 by yow » 10年前

GRAM さんが書きました:私がしたのは、コンストラクタとデストラクタを呼び出すのが不可能ではないという話であり、
そうするのが適切かどうかという話ではありませんのでご了承ください。
ご丁寧にありがとうございました。実際にやって見ました所、初期化と終了処理の関数を作ってコンストラクタ、
デストラクタの中身をそれぞれに移し替えた方がプログラムの変更が容易でしたのでそうさせて頂きました。
この方法が正しいかは分かりませんが、一応問題なく動作致しました。

閉鎖

“C言語何でも質問掲示板” へ戻る