Out of Memory

本ブログは更新を停止しました。Aerieをよろしくお願いいたします。

目次

Blog 利用状況

ニュース

2009年3月31日
更新を停止しました。引き続きAerieを御愛顧くださいませ。
2009年2月3日
原則としてコメント受付を停止しました。コメントはAerieまでお願いいたします。
詳細は2月3日のエントリをご覧ください。
2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

αετο? / aetos / あえとす

シャノン? 誰それ。

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

書庫

日記カテゴリ

静的メンバの使い道

zeeさんのネタに触発されて。

静的メンバって、どうやって使うのが正道なんでしょうね?

最初に一つ言っときます。コンストラクタ(というかnew)は静的メソッドの一種と考えることができます。
正確に言うと、コンストラクタは静的メソッドとインスタンスメソッド(※)のハイブリッドみたいな特異なメソッドです。
その内部ではインスタンスメンバにアクセスできるという点ではインスタンスメソッドですが、クラスに対して「新しいインスタンスを作ってよ」と依頼するという点では静的メソッドです。

※:静的メンバの対義語は動的メンバで、インスタンスメンバの対義語はクラスメンバなんでしょうが、どっちもいまひとつ分かりにくいので、ここでは「静的メンバ」と「インスタンスメンバ」を対義語として用います。

ま、それは置いといて。

静的メンバの使い道を4つほど考えてみましたが、どれもしっくりきません。
どなたか、「これぞ静的メンバだ!」というものをご存知でしたらご教示ください。

1:インスタンスの集合が持つメンバとして

先日のオブ熱イベントでちらっと言いましたが、クラスは基本的に、インスタンスの集合です。
集合ということは一種のコレクションであると考えられます。
そこで、例えば社員クラスを社員インスタンスのコレクションであると考えると、そのコレクションの属性として総社員数が考えられます。
しかし、社員クラスを社員コレクションとするのではなく、別途、社員コレクションクラスのインスタンスを作って管理した方が柔軟なように思えます。

2:シングルトンとして

シングルトンというのは、インスタンスを1つしか持たないクラスです。
身近な例では、Console.WriteLine とか、MessageBox.Show とかがこれにあたると考えられます。

Console.WriteLine は、実は Console.Out.WriteLine と同じ意味です。Console.Out は Console クラスの静的プロパティですが、同時に TextWriter クラスのインスタンスでもあり、そして、TextWriter.WriteLine はインスタンスメソッドです。
Console.WriteLine は、よく使うので短縮形が提供されているに過ぎず、静的なのは Console.Out です。
これが静的なのは、標準出力は1プロセスにつき1つしか無いからです。

MessageBox.Show はどうでしょう。
MessageBox に似たフォームを作ることは簡単にできます。そのフォームのインスタンスを作って ShowDialog すれば、MessageBox.Show と同じ効果が得られます。
フォームのインスタンスは一度にいくつでも作れます。しかし、ShowDialog できるのは、1つのスレッドにつき同時に1つだけですから、いくつも作るメリットはほとんどありません。
MessageBox は、インスタンスを作られては困るわけではないけれど、たくさん作っても仕方がないのでシングルトンなんだと思います。

シングルトンは、インスタンスが無いわけではなく、唯一のインスタンスに対するアクセス手段が静的なだけであり、本質的にはインスタンスメンバを使っていると言ってよいでしょう。
これも静的メンバの本質に迫るものではありません。

3:クラスが名前空間の場合

名前空間という言葉には、狭義の名前空間と広義の名前空間があります。
狭義の名前空間は、言語機能の namespace によって実現されるものです。
広義の名前空間とは、ある名前が一意になる範囲のことで、これは概ね、スコープのことです。
クラスが違えば、複数のクラスに同じ名前のメンバがあってもいいですよね。
メソッドが違えばローカル変数名が同じでもバッティングしませんし、あるメソッド中でのローカルスコープも名前空間になります。
このように、クラスは名前空間の機能を兼ね備えています。

俺が好んで使う例として、Directory.CreateDirectory があります。あるいは、Math.Sin もそうです。
これらにおける Directory クラスとか Math クラスは、オブジェクトの集合でもないし雛型でもありません。
これらは名前空間としての役割しか持っていません。

実のところ、こいつらは、言語仕様がどのクラスにも属さないメソッドを許すのなら、そこにあっても何も困らない連中です。
クラスのメンバでないメソッドを許さない言語の制限をなんとかかいくぐった、苦肉の策と言えるでしょう。

余談ですが、「メソッド呼び出しはオブジェクトに対するメッセージを投げることであり、仕事の依頼である」という観点に立つと、これらの異常性が際立ちます。
新しいディレクトリを作ってくれという依頼は、よくわからない Directory クラスではなく、ファイルシステムに投げるべき注文でしょう。
Math クラスに至っては何が何やら。

なお、C# 2.0 の静的クラスや、C# 3.0 から導入される拡張メソッドもこの部類です。

4:メンバが定数の場合

C# の const は、同時に静的でもあります。
C# では、値型か string しか、const にすることができません。
ですから、実質的に定数であるが、値型でも string でもない場合、仕方がないので readonly static として、定数として扱います。
これは2と3を足したような理由で、一番しょーもないものだと思います。

オブジェクト指向の中核要素であるクラスと、そのメンバという機能という観点から見て、静的メンバの有効な用法、その神髄とは一体何なのでしょうか?

投稿日時 : 2007年8月6日 17:24

Feedback

# re: 静的メンバの使い道 2007/08/06 17:47 凪瀬

staticと非staticという2分類で考えるから難しいんじゃないでしょうかね?

私のエントリで
http://blogs.wankuma.com/nagise/archive/2007/07/31/88042.aspx
オブジェクトが階層化しているね、という話をしていましたが、
classもそのオブジェクトの階層の概念の中に納まるんじゃないか、と発言しました。

すると、オブジェクトの階層の中で、親側のメンバで管理すべきものは?という汎化した論点になるのではないでしょうか?

# re: 静的メンバの使い道 2007/08/06 19:00 シャノン

いろいろとモヤモヤしてきますねw
つきつめるとプロトタイプオブジェクト指向になってしまいそうだww
ファクトリパターンとかも絡めると思考が広がりますねー。

# re: 静的メンバの使い道 2007/08/06 19:44 valp

MessageBox.Showが2. シングルトンになるのは新鮮でした。今までWin32のMessageBox関数をラップしただけだから理由としては3. 名前空間に当たると思っていました。

また、MFCやATLでは、ウィンドウに当たるCWnd, ATL::CWindowのインスタンスメンバとしてMessageBoxが用意されているところから、MessageBoxは、ウィンドウハンドルが指すインスタンスに対するメソッドだという見方もできるのではないのかと思います。

ただ、Mathの場合、この話の延長でDoubleやSingleのインスタンスメソッドにSinやLogなどを持たせたら、と考えるとAtan2はどうしようってなるんですけどね。

# re: 静的メンバの使い道 2007/08/06 23:58 やまだ

> 正確に言うと、コンストラクタは静的メソッドとインスタンスメソッド(※)のハイブリッドみたいな特異なメソッドです。
Java だと、本当に new 命令と、そこでできたインスタンスのメソッドの初期化メソッド呼び出し命令の二つに分解します。

> クラスは基本的に、インスタンスの集合です。
集合っていうよりは、カテゴリではないかと思いますが。
> そのコレクションの属性として総社員数が考えられます
グループ会社で同じ形式の社員クラスを採用した場合とかを考えると、クラスではなく親会社社員コレクション、子会社社員コレクション、グループ会社社員コレクションとして管理した方が良くないでしょうか?また読み違えてます?

>2:シングルトンとして
「唯一のインスタンスに対するアクセス手段が静的」にするために、静的メンバを利用していると考えられると思います。
ただ、なぜ静的メンバを使っているか、それはクラス名で唯一に特定できるからです(同じクラスローダー中では、ですが)。
裏を返すと、唯一に特定できればオブジェクトのインスタンスメンバでも良いことになりますね。
#っていうことを考え始めると、凪瀬さんが言われていることの方が考えやすいような気もしてきます。

# re: 静的メンバの使い道 2007/08/07 0:16 シャノン

> MFCやATLでは、ウィンドウに当たるCWnd, ATL::CWindowのインスタンスメンバとしてMessageBoxが用意されている

MessageBox は第一引数に HWND を取るから…MFC などは HWND を引数に取るものはみんな CWnd のメンバにしてしまっているような印象を受けますね。
少なくともあれは、引数に渡したウィンドウに対して何か働きかけるものとは考えにくいですから、MFCのアプローチが適切だとはあまり思えませんね。

> Mathの場合、この話の延長でDoubleやSingleのインスタンスメソッドにSinやLogなどを持たせたら、と考えると

それはやりすぎだと思いますね。
C# の拡張メソッドの応用で、System.Math モジュールを参照設定した時だけ Double.Sin がメンバとして登場する、みたいな形も面白いかもしれません。
ただ、やはり、「すべてのメソッドは何らかのクラスに属さなければならない」という制限がなければ、もっと素直な形になる気がします。

# re: 静的メンバの使い道 2007/08/07 0:18 シャノン

> 集合っていうよりは、カテゴリではないかと思いますが。

うーん…集合もカテゴリも似たようなもんだと思いますが、ぜんぜん違いますかね?

> また読み違えてます?

いえ。俺もコレクションの方がいいんじゃない? とは書いてます。
ただ、静的変数の教科書的サンプルとしてはありそうですよね>総社員数

> (同じクラスローダー中では、ですが)。
> 裏を返すと、唯一に特定できればオブジェクトのインスタンスメンバでも良いことになりますね

拡大させて考えていくと、ファクトリメソッドパターンで、1つのファクトリからは1つのインスタンスしか生成できない…とかいうのもアリかもしれませんね。
いろいろなケースを絡めて考えるのは面白いです。

# re: 静的メンバの使い道 2007/08/07 1:19 やまだ

> うーん…集合もカテゴリも似たようなもんだと思いますが、違いますかね?
単に私の中での「イメージ」での話ですが、「集合」っていうと「要素が確定しているもの」というニュアンスがあります。要素が増えたり減ったりすることはあっても、スナップショットで見れば確定している。裏を返すと、要素の集まりにより定義されるものが集合。
「カテゴリ」は単なる分類子で、要素があるなしとは関係なく存在する。
ってなイメージなんですが。

> ただ、静的変数の教科書的サンプルとしてはありそうですよね>総社員数
そうですか?シングルトンの方がありそうな例だと思いますが。
そもそもどうやって総社員数をカウントするんですか、って書きかけて……理解。newのときに静的メンバを+1していくんですね。うー、なんか気持ち悪いんですが。裏で勝手にカウントされるならともかく、そういうコードを書くのって。
それって、オブジェクト指向データベース(懐かしい……)っぽい考え方かもしれない、とか思ったり。

>> 裏を返すと、唯一に特定できればオブジェクトのインスタンスメンバでも良いことになりますね

オブジェクトを間接参照なしで By name でアクセスできるようになれば、ってこれもOODBの話?

# re: 静的メンバの使い道 2007/08/07 11:40 渋木宏明(ひどり)

僕は「4」のパターンがほとんどです>静的メンバの使い道

単純な数値型・文字列型を配置する場合もありますが、それよりはクラス内部で参照する Dictionary<T,V> や List<T> を配置する場合が多いかな?

# re: 静的メンバの使い道 2007/08/07 11:46 シャノン

ちなみに、「集合」と言うときは、数学の集合論を意識してます。
そういえば、「カテゴリ論」っていう数学もありますね。集合論のすっげぇ高度なやつ。

> オブジェクトを間接参照なしで By name でアクセスできるようになれば

IMoniker?

OODBってのもよくわかんね。

# 2007年8月の月間ページビュー 2007/09/02 9:47 .COM -どっとこむ-

2007年8月の月間ページビュー

# Hi there, every time i used to check website posts here in the early hours in the morning, for the reason that i enjoy to find out more and more. 2018/11/03 23:25 Hi there, every time i used to check website posts

Hi there, every time i used to check website posts here in the early hours
in the morning, for the reason that i enjoy to find out more and
more.

タイトル
名前
Url
コメント