2004/05/27

ガッ

最近は火曜日以外は時間にあんまり拘束されない日々なので、なかなかいい生活を送っています。とりあえず起きて外出する準備に時間をかけられるというのがスバラシイですね(3年までは授業15分前に起きた→とりあえず着替えて自転車でダッシュ、とかだったのでコンタクトいれてる余裕とか全然なかったし)。

ソフトの趣旨がどうのこうのはともかくとして、窓の杜は本当にこれがお気に入りなのかと小一時間問い詰めたくなるのは私だけでしょうか。

さて、今日はなんだか研究室で課された課題をしかたなく発表する日でして、発表してきました。内容はGTKで書かれたお絵かきアプリケーションに色選択ダイアログを追加しろって感じでして、なんだ、ダイアログ追加するだけだったら2日もあればできるんじゃないか(Windowsなら30分でできるはずっ)、とか思いつつ、GTKはまったく分からないのでとりあえず着手してみたのがGW明け。

…とりあえず1日目でどういう処理になってるかC++のサンプルソースを読んで、2日目にリファレンスマニュアルでカラーダイアログの出し方を調べて、ボタン追加してダイアログ追加して色変わるようにして終了。…締め切りまで後2週間も残ってるので、とりあえずもうちょっと深くコードを追ってみることに。

なるほど、Windowsはあらかじめ向こうで用意されたメッセージがウィンドウプロシージャに飛んでくるけども、GTKはシグナル(Windowsでいうところのメッセージ)に対する応答をコールバック関数で指定していたのか。…って、C++でウィンドウウィジェットをカプセル化しても、シグナルに対する応答はコールバック関数だから、thiscallなC++ classのメンバ関数は呼べないじゃないか。ということで、どうなってるか見てみたら、g_signal_connectの4つ目の引数のvoid*ポインタにthisを渡して、グローバルに置いたコールバック関数からオブジェクトを参照してメンバ関数を呼んでいるのか!

これじゃ、メッセージ応答のメンバ関数をpublicに置かなきゃならないわけで、クラスをカプセル化してる意味がありません。これ書いたヤツ出てこいって感じです。とりあえず、これじゃ全然クラスにしてる意味がない(無いわけじゃないけど、オブジェクトの露出が激しすぎます)。というよりも、応答するべきSignalの数だけただオブジェクト参照でメンバ関数を呼ぶだけのグローバル関数とか作ってたらコードサイズ(まぁ、ソースサイズも)がふくれてどうしようもないので、クラスにstaticなコールバック関数を用意してそれで振り分けるように1から書き直し、と。まぁ、publicにおかなきゃならない云々はコールバック関数をfriend関数にすればいいんですが、それにしてもコールバック関数を作るたびにそれ全部friendにしてたら結局カプセル化の意味無いですよね。

とまぁ、そんなかんじで書き直して完成しましたが、buttonをclickしたときのシグナルの応答コールバックだけなぜか他のイベントコールバックより引数が一つ足りない(GdkEvent系引数がない)というヒドイ仕様なので振り分けようのウィンドウプロシージャ風関数も素直に振り分けられないし、GTKもなんだかなぁ。

とりあえず、イベントコールバックでbuttonのclickだけ引数が1個少ないという設計は、さすがに設計思想を疑いたくなるような気分なんですが(こういうイベント応答コールバックは引数の数とタイプを合わせて汎用的な振り分けができるようにやるのが普通かと思ってたんですが…)、どうなんでしょうね。

そのほかいくつか気付いた点を。

プレーンなCではコメントに // を使っていけない?

なんか、5人中4人(つまりオレ以外だ)が今回の課題をプレーンなCで書いてたんですが。

大昔のCならともかく、C99からは「正式に(ってことは、わりと多くの処理系では既にサポートされてた)」 // をコメントとして使えるようになってますから、「プレーンなCでは // というコメントは使っちゃダメだよ」とか言うような(多分に宗教的なにおいのする)コーディング規則は「C99から正式にコメントとして利用出来ますから問題ないのでは?」とはっきり言ってしまった方がいいかと思います。いや、ホントに。まさか大昔のコンパイラをターゲットにしているのだろうか?

C++でstdio.hを使うのはどうなのか

まぁ、これは私なんですけど、べーつにC++でiostreamじゃなくてstdioつかってもいいじゃないですかー。ただ、標準出力とかストリームのシークポインタがずれるとかいう問題があるのでstdio.hとiostream.hとiostreamをまぜるのはよくないのは事実。

というか、だれも指摘しなかったけどC++で書いてるのならstdio.hじゃなくてcstdioつかってstd::printfを用いるべきだろうというのはまさにその通りですね。いや、cstdioとかすっかり忘れてたし。というか、そもそもprintfはデバッグにしか使ってませんし(Linux、というかgcc環境じゃデバッガの使い方知らないので古き良きprintfデバッグでがんばっております)

うされもん @acidlemonについて

|'-')/ acidlemonです。鎌倉市在住で、鎌倉で働く普通のITエンジニアです。

30年弱住んだ北海道を離れ、鎌倉でまったりぽわぽわしています。

外部サイト情報

  • twitter
  • github
  • facebook
  • instagram
  • work on kayac