「いやあ、ボクはいま、受験生なので..」と、当り障りなくごめんなさいしたところ、しばらく間を置いて、「そうか、それなら仕方ないか..これ、おまけしといてあげるね」と、今日は消費期限切れかけの弁当を2つも入れてくれたのでした。俺が何したっちゅーんじゃい。自問自答していると「消費期限切れかけだから、早くたべてね。言ってくるではないですか。早くたべてね..あたしも消費期限切れかけだから早くたべてね..と聞こえなくもないその台詞。ご好意に、あんたは、とっくの昔に、消費期限切れとるやろー!とも言えない、やねうらおは、あ痛ててて〜と思いながらそのコンビニを後にしたのでした。ごめんな、おばちゃん。いうか、このおばちゃん、悪い人でないだけにこういうことされるとホント、辛いんだよな〜。第B1回の最後に書いてある内容は、波乱が波紋を呼んだようで、さまざまな人から質問を受けたました。某所で真剣に議論してくださった方もおられます。私の日記にそこまでしていただいたのではあまりにも申し訳ないので、少し補足させていただきたいと思います。問題の部分を再掲します。一つの問題というのは、アプリケーションクラスにつき一つ用意しなければならないものを記述するためのC++の構文が存在しないことです。あるクラスXYZのstaticなメンバにしてしまうと、それは他のスレッドからも参照できてしまいます。アプリケーションクラスにつき一つにしたければ、アプリケーションクラスのメンバとしてXYZを持たせるしか無いのですが、そうすると、クラスXYZは、モジュール性(modularity)を損ねてしまいます。私は、この部分に関してかなり独りよがりな表現をしていることをお詫びしなくてはなりません。ここで言う、モジュール性とは何を意味するのか?そして、アプリケーションクラスとは具体的には何を指すのか?また、なぜそのようなことをしないといけないのか?など、不明な点が多すぎます。おまけにこれを読み解く上で重要な部分を誤記していることもお詫びしなくてはなりません。アプリケーションクラスにつき1つではなく、アプリケーションクラスのインスタンス1つにつき1つです。用語の定義が曖昧なのは、ある程度大目に見ていただければ幸いです)まず、「モジュール性」という言葉のニュアンスについて考えてみましょう。質問をしていただいた方は、それぞれオブジェクト指向に関しては、相当、造詣が深い方ばかりだと思います。この部分にハテナマークが出たのだと思います。RAD系のツールを使ったことのある方ならばご存知だと思いますが、それぞれの部品としての完成度が非常に高いのです。C++のクラスもまた、ひとつの部品とみなせますが、私としては、RAD系ツールほど完成された部品とは到底、考えられません。第B7回の委譲最適化にしてもそうですが、OOPに詳しい人ならば、どうして同じインターフェースを持っているクラスをまた作らなくてはならないのだろう?だとか、どうして委譲する必要があるのだろう?とか、さまざまな疑問があがるはずです。OOPの世界で考えられるモジュールとは、普通、機能レベルでの完結を意味するでしょう。C++の何が不足なんだい?と。第B7回のようなことをする必要があるんだ?と。言うまでもなくプログラムは、部品だけでは、完成しません。それらをジョイントする部分が必要です。この部分は必要になるごとに書かなければなりません。この部分を、誰がいつ書くのかという点において、私はかねてから非常に疑問があるのです。一つのプロダクトを完成させようと思うと、このジョイントする部分も当然必要になるわけですが、この部分を毎回毎回、そのアプリケーションに合わせて書いているような気がしてならないのです。従来のOOPパラダイムでは、この部分の再生産性が、非常に低いと思うのです。Xの現存するインスタンスすべてへのチェインを得るにはどうすれば良いのでしょうか?一つの案は、これのコントロールクラスをXの“外側”に書くことです。m_chain;};あとは、必要に応じて、m_chainを辿れば良いでしょう。通例、推奨されるC++のプログラミングというのは、そういうスタイルだと思います。Xが部品だとしたら、XControlはそのジョイントというわけです。現実的にC++でプログラミングを行なっている場合、それが現実的な解決策だということはわかっているつもりです。それでも、あえて言わせていただいきたいと思うわけですよ、それで本当にいいのか?と。Xは、頻繁にチェインを辿る必要があるとします。XはDirectDrawSurfaceのクラスで、ディスプレイモードの変更等に応答して、すべてのSurfaceがLOSTするので、Restoreするためには全インスタンスを知る必要があるとします。そのときに、こんな風にXControlを通して、チェインを管理していたのでは、「ディスプレイモードの変更等に応答する」部分(メッセージ処理するのだから、通例フレームワーク)が、事前にXControlのありか(インスタンスの所在)を知らなくてはなりません。XControlのインスタンスが1つだとも保証されていません。要するに、こういうライブラリ設計をしてしまうと、すぐに破綻するのです。手段はいろいろありますが、これをスマートに解決する方法はC++にはありません。これを破綻とは感じないベテランプログラマも多数おられるのも、わかります。何と言われようと、私はC++のクラスがプリミティブな意味での部品レベルの完結しかしていないがために、それらをアセンブリする余計な手間が発生してきているように思えるのです。ひとりの人が設計したライブラリを使うユーザーが、そのライブラリの部品同士を結合するためのジョイント部分を書かなければならないような気がするのです。この部分は、私に言わせれば、まったくの無駄な部分なのです。(私が考える超強力なテンプレート機能と、いくつかの機能拡張を行なったC++のsupersetでは、少なくともジョイント部分の半分ぐらいは軽減されます...される気がします...されるといいな〜とか思います←なんだか弱気やね^^)XControlについて、もう一つの実装案を考えてみましょう。m_chain;にinsert(this)して、Xのデストラクタでerase(this)すればどうでしょうか?要するに、XControlをXの内側に“閉包”してしまうのです。この実装案は、ある程度、うまくいきます。「ディスプレイモードの変更等に応答する」部分からは、このm_chainを辿ればいいわけですから。ところが、このstaticなメンバ変数というのが曲者で、これを書いてしまった時点で、アプリケーションに唯一しか存在できません。これではまずい状況も多々あるのです。それが、前述のようにマルチスレッドでプログラミングしていて、アプリケーションクラスが、「2つのスレッド(メッセージポンプ+ワーカー)+自分の所有する窓を1つ」持つような場合、アプリケーションに唯一ではなく、アプリケーションクラスのインスタンスに一つにつき、そのチェインが1つ欲しいのです。これをどこに書くかということです。そりゃ、アプリケーションクラスのメンバとしてm_chainを持たせればOKなのは言うまでもありません。するとclassXの設計者がアプリケーションクラスについて知っていなければならなくなります。これが凄く理不尽に感じるのです。普通は、さきほどのようにXControlというクラスを作って、こいつのメンバをアプリケーションクラスのメンバとして用意するような実装にするでしょう。すると、「ディスプレイモードの変更等に応答する」部分に、ユーザーが手を加えなければならないというわけです。これで本当にモジュールと言えるのか?プログラミング用語として従来使われている意味ではなく、ひとつのユニットとして見たときの完成度と独立性すなわち相互依存性の少なさ、部品としての使いやすさ、機能レベルの完結性等々を考慮したときに、モジュラリティがあると言えるのかと。これでもやはり私が、何のことを言っているかわからない人にはわからないでしょう。理念は置いといて、実装技術で言えば、ownerポインタが欲しいのです。インスタンスの生成/消滅に関して、もっとインテリジェントなシステムが必要なのです。それは、必ずしもスマートポインタ的なメモリ管理のことを意味しません。私のプログラミング理念を実現しようとすれば、少なくともインスタンスは、自分が誰によって作られたのかを知る手段が必要になります。OOPのパラダイムからは外れるかも知れませんが、これは、ある程度納得していただけると思います。自分がどこで生成されたのかを知る手段も必要になります。んっ?どこで?と思われる方が大半でしょう。生成されたリージョンです。詳しいことを、ここに書くこともないでしょう。いまの仕事がひと段落したら、オブジェクト指向スクリプトを実装するので、それをもって回答としたいと思います。(しかし、年内にあと3本ぐらい開発を控えてるんだけどなぁ..大変だなぁ。00/08/05このスーパープログラマーへの道ですが、回数は16進数表記です。もんで「第57回」を「第五十七回」と読むのは誤りです。読むと、どうでしょうか。これでは、何のことかわからんわい!>俺あのあと、いろいろ考えて、DIB(CreateDIBSectionで作ったものに限る)は、DCも取得できるのでリソースの枯渇にさえ気をつければ案外便利ではないかという結論に至りました。スピードも、DirectDrawSurfaceからDCを取得して描画するのであれば、MMXできちきちに書いたコード(32bpp->32RGB,32BGR,24RGB,24BGR,16bppRGB555,16bppRGB565,8bpp)には劣りますが、それなりに速いのです。素のPentiumで書いたコードよりは、よっぽど高速です。ハードウェア側で何とかしてくれるのでしょう。(というか、Windowsが出てから発売されたビデオカードは、それくらいハードの設計者も考慮しているに違いない)ということで、なかなか便利なDIBSectionを積極的に使うことにしました。GDI系の描画でよく使うCOLORREFは、下位からR,G,Bである。それに対して、一般的なビデオカードでは、これとは逆順であることのほうが多いのです。DirectDrawSurfaceもCOLORREFと逆順です。CreateDIBSectionで作るとどうなるかというと、ピクセルフォーマットを指定せずに32bppのDIBを作れば、後者になります。なんや?それやったらCOLORREFなんて、やめちまえとか思うけど、いまさら言っても後の祭りなのでしょう。