シングルトンパターンの破棄

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

シングルトンパターンの破棄

#1

投稿記事 by dic » 16年前

デザインパターンの一種 シングルトンパターンについて質問です

クラスA にコンストラクタ、デストラクタを定義し、クラスAにシングルトンパターンを適用すると
デストラクタが呼ばれなかったので、メソッドRelease() を追加し、その中で明示的にdelete したら
うまくデストラクタが動作しました

このように、シングルトンパターンでは明示的に _instance を delete しないとデストラクタは
呼ばれないのでしょうか?

私の考えでは、return 0; のところで クラスAのデストラクタが呼ばれると予想していたのですが
どうも違ったようでした
#include	<stdio.h>

class	A
{
	static	A*	_instance;
public:
	A();
	~A();
	static	A*	Instance();
	void	Show();
	void	Release();
};

A*	A::_instance = 0;
A*	A::Instance() {
	if( _instance == 0 ) {
		_instance = new A;
	}
	return _instance;
}
A::A() {
	printf( "A construct.\n" );
}
A::~A() {
	FILE	*file = fopen( "destruct.txt", "wt" );
	fputs( "destruct called.\n", file );
	fclose( file );
	printf( "A destruct.\n" );
}
void	A::Show() {
	printf( "A::Show call.\n" );
}
void	A::Release() {
	FILE	*file = fopen( "release.txt", "wt" );
	fputs( "release called.\n", file );
	fclose( file );

	//	明示的にdeleteする
	delete _instance;
	_instance = 0;
}

int	main()
{
	A::Instance()->Show();
	A::Instance()->Release();

         return 0;
}

array

Re:シングルトンパターンの破棄

#2

投稿記事 by array » 16年前

質問されている内容からずれてしまいますが、気になったので・・・
シングルトンパターンは、プログラム全体でただ1つしか存在しないことを保証するというものらしいですので、コンストラクタ、コピーコンストラクタなどのアクセスは「private」にして禁止しておくべきだと思います。


備考URL:http://www.geocities.jp/ky_webid/design ... n/009.html

kazuoni

Re:シングルトンパターンの破棄

#3

投稿記事 by kazuoni » 16年前

恐らく動的確保しているからではないでしょうか?
(間違っていたらすみません)
環境によっては、プログラム終了時に動的確保した変数を解放することもあるかと思いますが・・・。

やはり、ユーザーが解放しなければならないかと。

>私の考えでは、return 0; のところで クラスAのデストラクタが呼ばれると予想していたのですが
確か、スコープを抜けるときだったと思うので、
voidの時もデストラクタは呼ばれます。(もしかしたら環境によろのかな・・・?)
#include<iostream>
using namespace std;

class A{
public:
	A(){cout << "A construter" << endl;}
	~A(){cout << "A destructer" << endl;}
};
void func()
{
	A a;
}

int main()
{
	func();
	return 0;
}
>コンストラクタ、コピーコンストラクタなどのアクセスは「private」にして禁止しておくべきだと思います。
自分も同感です。
っというか、普通に生成できちゃったら、シングルトンパターンの意味がないですからね^^;

たかぎ

Re:シングルトンパターンの破棄

#4

投稿記事 by たかぎ » 16年前

シングルトンにするなら、普通はこんなかんじでしょう。
class	A
{
private:
	A();
	~A();

	A(const A&);
	A& operator=(const A&);
public:
	static	A*	Instance()
	{
		static A a;
		return &a;
	}
	void	Show();
};
ただし、マルチスレッド対応を考える場合はこれではすみません。

dic

Re:シングルトンパターンの破棄

#5

投稿記事 by dic » 16年前

arrayさん kazuoniさん たかぎさん
回答ありがとうございます

そういう使い方もあるんですね
私の持っている参考書が古いのかもしれません
ちなみに これですが
http://www.amazon.co.jp/%E3%82%AA%E3%83 ... 214&sr=8-2
発売日が1999年ですね

もっと深く追求すると色々でてくるかもしれないですね

今回の場合は特に制約などないので明示的にRelease()を作って呼び出すことにします

YuO

Re:シングルトンパターンの破棄

#6

投稿記事 by YuO » 16年前

GoF本はパターンのカタログであって,実装方法のカタログではないですからね。

Modern C++ Designなんかでは,C++におけるSingletonの実装についての話があります。
http://www.amazon.co.jp/dp/4894714353/
たかぎさんの書かれた,マルチスレッドの考慮の話や,破棄後にアクセスがあったらどうするか,などの話も載っています。

Justy

Re:シングルトンパターンの破棄

#7

投稿記事 by Justy » 16年前


>このように、シングルトンパターンでは明示的に _instance を delete しないとデストラクタは
>呼ばれないのでしょうか

 この質問は前回のスレで解決していたものと思いましたが、
内部的に newで生成しているシングルトンクラスは、deleteを行う Release関数を
作成しておき、newした段階で std::atexitを使ってそれを呼び出すように作っておけば、
明示的に Release()を呼ばなくてもプログラム終了時に解放してくれます。

dic

Re:シングルトンパターンの破棄

#8

投稿記事 by dic » 16年前

>Justyさん
前回の回答ありがとうございました
しかしながら私の理解不足により、飛ばしていました
具体的に言うと std::atexit 関数が プログラムがアンロードされるのに
何によって管理されているのか、どのように動作するのかがが理解できてませんでした

return 0; よりも後に実行されるのか?kernel.dllが管理してるのか?
Windowsのイベントドリブン処理方式ならなのかなど具体的なイメージが沸きませんでしたので
もうしわけありませんでした

dic

Re:シングルトンパターンの破棄

#9

投稿記事 by dic » 16年前

>YuOさん
参考書を教えていただきありがとうございます

ようしゃなく英語ですね
ただいま高校からの英語をやり直ししている最中であります

日本語改訳版がでるといいですが、ジェネリックプログラムもまだ、手がおいつかないので
ブックマークにいれておきます

YuO

Re:シングルトンパターンの破棄

#10

投稿記事 by YuO » 16年前

> 具体的に言うと std::atexit 関数が プログラムがアンロードされるのに
> 何によって管理されているのか、どのように動作するのかがが理解できてませんでした

std::atexitはmainから戻った or std::exitが呼ばれた後に呼び出される,標準C++関数です。
処理系によっては,staticなオブジェクトのデストラクタを呼び出すために使われています。


> ようしゃなく英語ですね

Modern C++ Designは翻訳された本ですよ (Amazonのなか見検索参照)。

dic

Re:シングルトンパターンの破棄

#11

投稿記事 by dic » 16年前

> std::atexitはmainから戻った or std::exitが呼ばれた後に呼び出される,標準C++関数です。
> 処理系によっては,staticなオブジェクトのデストラクタを呼び出すために使われています。
なるほどそういうことなんですね
色々試してみます

> Modern C++ Designは翻訳された本ですよ (Amazonのなか見検索参照)。
おお、日本語だった
しかし、私にはちょっと難しいかもしれません

閉鎖

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