引数をポインタで渡すと、保存するのかも???

in

C++の実装で関数の引数をリファレンスにするか値またはポインタにするかについては一応の目安があって

  1. オブジェクトを引数とする場合はリファレンスを使う
  2. 組込型を引数とするときは値で渡す
  3. 関数内で組込型を変更する場合はポインタ渡し

もちろん、変更の有無に関してconst付けたりとか、3.についてchar*で文字列を渡す場合はどうなんだ?(僕の場合文字列を渡すには99%がstd::stringにしてますからあまり考えなくとも済みます)とか他にも考えることはあるのですがまぁおおよそこんなガイドラインで不自由今日までやってきました。ところが、積ん読だったC++ スタイルブック (IT Architects’ Archive―CLASSIC MODERN COMPUTING)という本をパラパラ眺めていたら、

非constの参照パラメータは、その関数がオブジェクトに非const演算を実行する可能性があることを示すが、その関数がオブジェクトへの参照を保存するかどうかは示さない。参照の代わりにポインタを使用して、引数として渡されたオブジェクトへの参照またはポインタを、その関数が格納することを示すべきである。
(中略)
ポインタを使用すると、オブジェクトへの参照が格納される可能性があるというヒントを与えることになる。

恥ずかしながらこれ全然知りませんでした。考えたこともなかったです。基本的には上記のようなガイドライン、つまり受け渡しの効率(と変更の有無)だけに注目してインタフェースを決定していたわけです。しかもなぜポインタで受け渡しすることがオブジェクトへの参照が格納される可能性があることになるのかいまひとつよくわかりません。同書の例にもあるように、

class foo
{
  public:
    foo() {};
    void voice_of_woo() { pw_->voice(); };
    void var(const woo& w) { pw_ = &w ; };
  private:
    const woo* pw_;
};

なんてコードもアリにはありなのでvar()が必ずしも

void var(const woo* w) { pw_ = w ; };

が、関数が「オブジェクトへの参照を保存するだろう」と予測できるわけではないと思うし、オブジェクトへの参照を保存するからといって必ずしも引数がポインタである必要はないと思うのですが....少なくとも、少なくとも僕は、関数宣言だけをみて「wooオブジェクトへの参照が保されるんだな」なんてことは気がつかない。どちらの場合も、ドキュメントやソースコードを読んではじめてその挙動を理解するってことになる気がします。

単なる慣習のことを言っているとも思えませんしもう少し突っ込んだ解説が欲しかったのですが、残念ながらその理由は書いてありませんでした。こんな単純なサンプルで説明できることではなくてもっと深淵な理由を孕んでいる気もしますが無知なる僕にはハッキリとしたワケが解りませんでした。かとにかくすっきりしませんね。

boost::gregorian::dateの月(数値)の取得

boost::gregorian::dateでdateObj.month()すると、NovとかDecとかが返ってくる。dateObj.month().as_number()がデフォルトのほうが僕はいいと思う。月を取得して文字列が返るのは直感的では内容に思うのですが。いや、ハマったから言うのじゃありません... 

それにしても、boost::gregorianは重いですね。Regexなんかと併用するとプリコンパイルのメモリが足りないとか言って(VS2008)きて/zmするハメになります。こうなると大抵Intellisenseが壊れるのでまあ、今回のようにヘッダを読む羽目になるわけです。windowsアプリの場合、無理して使わないようにしようかと思います。

iPhone 3G3買いました

in

とりあえず、落としたりするのが怖いのでこれを注文した。ぱっぱり、ストラップがないのはなんとなく不安だけど、それがアップルのデザインポリシーなんだろうな。尊重したいと想ったけれど、ちょっと無理でした。

SHIELD iPhone 3G用シェルカバー アイボリーブラック
SHIELD iPhone 3G用シェルカバー アイボリーブラック
SHIELD
売り上げランキング : 23957

Amazonで詳しく見る by G-Tools

さぁ、これでどんな風に遊ぼうかなぁ。

鏡の国では不思議がたくさん

comp.lang.objective-cのConfusion with NSMutableStringのトピックに面白い(表現の)トピックがありました。お題は、以下のコードで、

NSString* path = @"~";
path = [path stringByExpandingTiledInPath];

pathが変更できるのは変じゃない?というものなのですが、それに対して

You haven't understood "Through the Looking Glass" :-)

というリプライがあって何か特別な慣用句なのかショボイ英語力の僕には知れませんが、言い得て妙な表現です。英語圏の人にはこれで「あっ!」って感じで腑に落ちるんでしょうかね。

そういえば、Objctive-Cを始めた頃、こんなコードを書いてしまったことがありましたがこれもhaven't understood "Through the Looking Glass"ですね。

Foo* foo = [Foo alloc];
[foo init];

チェシャ猫は何も言ってくれませんでした(*_*)。鏡の国は、不思議の国...です。

for_eachでメンバ関数を使う時の復習的自分メモ

in

for_eachでFuncにメンバ関数を指定するっていうお題はbins1st、mem_fun/mem_fun_refを使えってことになるのですがそれ以外にも落とし穴があります。なかなかまとめて説明しているものが見つからなかったので自分自身のおさらいを兼ねて...

MBTI性格テスト

in

影響されて、MBTIテストというのをお遊びでやってみた。

結果は、ご覧の通り。いいだか、わるいんだか。プログラマには向いているみたいです。一応、二度やってみましたがほぼ同じです。

ご覧の通り、直感力を鍛えねば....達人にはほどお遠い。

『プロダクティブプログラマ』あるいは化石プログラマの行く末

前半戦は読み物としてお気軽に楽しく読めたけど、後半は硬派で、

ソフトウェアの複雑化により技術者は急速に専門化に向かっています。専門化にはアプリケーションの種類別の専門化とプラット-フォーム別の専門化があります。専門化の進む「すばらしい新世界」に対応するためには、多言語プログラミングやドメイン特化言語を取り入れていくべきです。そうしなくては今後多く発生する新たな問題の解決は難しくなるはずです。今後5年の間に、ソフトウェア開発の様相は、今日とは全く違ったものに変わるに違いありません。

のくだりにはちょっとビビってます。

NSRuleEditorのローカライズ(その2)

前回のエントリで書いたようにNSRurleEditorではルールを作成に際してDelegateメソッドを通じて細かい制御をおこなうことができます。必須のDelegeteメソッドは3つ、

  1. ruleEditor:numberOfChildrenForCriterion:withRowType:
  2. ruleEditor:child:forCriterion:withRowType:
  3. ruleEditor:displayValueForCriterion:inRow:

NSRuleEditorのaddRowメソッド呼び出しのタイミングで左辺・述部・右辺についてそれぞれ呼び出されます。今回のサンプルで言えば初回時(ルート)では price/color/sizeの3つの選択肢があるので返す数は3。NSRuleEditorではこの数に基づいて、ruleEditor:child:forCriterion:withRowType:メソッドが3回呼び出します。このメソッドでは左辺3つの情報をNSDictionary形式にパックして返します。パラメータchild:(NSInteger)indexで表示位置を指定してきますのでindex(0)でpriceの情報を、index(1)でcolorの情報・index(2)でsizeの情報を返します。

NSRuleEditorのローカライズ(その1)

数日の間、アップルのサンプルPredicateEditorSampleをベースにNSRredicateEditorに取り組んでいます。複雑なインタフェースを簡単に実装できるのはありがたいのですがローカライズには問題があります。まず、単純なローカライズですがLocalizable.stringでははうまく変換されません。Cocoabuilder/Getting localized NSPredicateEditorによれば、NSPredicateEditorではローカライズファイルを明示する必要があるようで、暗黙にLocaizable.stringを参照してはくれないみたいです。メインバンドルに任意のstringファイルを作成して

[predicateEditor setFormattingStringsFilename:@"predicate.strings"];

として教えてあげる必要があります。また、ポップアップにあたる部分の書式は"%[xxxx]@"というように書きます。

NSPredicateの正規表現

NSPredicateでは正規表現もサポートしていて単にマッチングだけを目的とするのであれば、RegexKiOgreKitを導入する必要はありません。例えばURLマッチングであれば、

NSPredicate* reg = [NSPredicate predicateWithFormat:
  @"SELF MATCHES 'https?://[a-zA-Z0-9/.?_+~=%:;!#-]+'"];
if ([reg evaluateWithObject:source])
  {
     :
   }

Cocoaのメモリ管理関する3つのルール

in

Obujective-C 2.0の時代にアレなんですが、オブジェクトのretain/releaseに関しては時々混乱することがあるので「Learn Objective-C on the Mac」に載っていたCocoaのメモリ管理関する3つのルールをメモ。メカニズムを正しく理解するのも大切だけれど実際コードを書くときにスッっとでてくるガイドラインも大切ということで...

  1. オブジェクトをnew、alloc、copyで生成した場合、release/autoreleseメッセージを送信してオブジェクト解放の責任を負う。
  2. new、alloc、copy以外の方法でオブジェクトを取得した場合オブジェクトはautorelese対象であり、オブジェクト解放のために特になにかする必要はない。(ただし、ルール3には従う必要がある)
  3. もし、オブジェクトにretainメッセージを送信した場合、このretainに対応するrelese/autoreleseメッセージを送信する責任がある。

単純でわかりやすい。普段は1.を気をつけていればいいってことになります。僕が迷うのはアクセッサメソッドの実装で、オブジェクトの生成が離れた箇所に実装されているので迷います。本書にも載っていた、

setSomething:(id)someObject
{
  [someObject retain];
  [myObject release];
  myObject = someObject;
}

とするパタンと、

setSomething:(id)someObject
{
  [myObject release];
  myObject = [someObject copy];
}

のパタンで「アレ? retainするんだっけ?」みたいなヘモい混乱。上の例ならルール3、下の例ならルール1で(たぶん)もう迷わない(と思う)。

ホントにこれでいいのか疑問なコード

in

CEditBoxの幅を入力可能な文字数にあわせるとか、エディットボックス自体を右揃えにするなんてことは誰でも考えることだろうけど、皆どう実装しているんだろうか?僕は、

// Create Controll Font
m_ctrl_font.CreatePointFontIndirect(&logfont,pDC);
// Label A
tmpstr      = "LABEL A";
GetTextExtentPoint32(pDC->m_hDC,tmpstr.c_str(),tmpstr.length(),&textSize);
rect.top    = 20;
rect.left   = 20;
rect.bottom = rect.top  + (tm.tmExternalLeading + tm.tmHeight);
rect.right  = rect.left + textSize.cx;
CStatic* l = new CStatic;
l->Create(tmpstr.c_str(),SS_LEFT|WS_VISIBLE|WS_CHILD,rect,this);
l->SetFont(&m_ctrl_font);
// Edit A
int edge_w = GetSystemMetrics(SM_CXEDGE);
GetTextExtentPoint32(pDC->m_hDC,_T("1234567890"),10,&textSize);
rect.left   = rect.right + tm.tmMaxCharWidth;
edit_a_right = rect.right  = rect.left  + textSize.cx + (edge_w * 2);
CEdit* e = new CEdit;
e->CreateEx(WS_EX_STATICEDGE,_T("EDit"),"",
  ES_LEFT|WS_CHILD|WS_VISIBLE|WS_TABSTOP,rect,this,WM_USER+1);
e->SetFont(&m_ctrl_font);

みたいなコード(全ソース)を書いたりしていたのだけれどこれってかなり面倒。リソースエディタでペタペタ貼り付けて適当な大きさに並べておいてOnSize()あたりで幅を調整するのもありかと思うけどそれでも面倒な事は同じですよね?結局、コントロールの数だけ上記のようなコードをゴリゴリ書くわけです。

ちょっと変態的な関数ポインタ

in

メンバ関数のポインタをvectorに突っ込んで使おうとして手間取ったのでメモ。ググってみたらstructに関数ポインタ変数を宣言すれば簡単にvectorに格納できるのはすぐにわかったのだけれど使い方で一晩悩みました。まだまだです>自分。とりあえず、グローバルな関数なら、

UndocumentedGoodness

in

CocoaDevのUndocumentedGoodnessというトピックで、キーチェーンで新しくパスワードを作成する際に使われているPasswordAssistantPanelを使っちゃおうっていうTIPSが紹介されています。この「パスワードアシスタント」はキーチェーンアクセスで「新規パスワード項目」を作成するとき使うツールなんですが、

  • 英単語混じり
  • 文字と数字
  • 数字のみ
  • ランダム
  • FIPS-181準拠

といったルールを選択することでそのルールにあったでパスワードを自動生成してくれてしかも強度まで表示してくれるすぐれものです。忙しい日々テキトーなパスワードを考えるのすら面倒な僕には重宝しそう。

MacPowerの最新刊が面白い

復刊後、デザイナー向けの雑誌になった(ように思える)MacPowerの最新刊がなかなか読み応えがある。今後もこの路線が続いてくれると定期購読復活ということになりそうなのだけど...

雑誌とはいえ、ジョブズの記事は読み応えがあるし、XCodeについての日本語の記事なぞPeopleやFanではなかなかお目にかかれないわけで、かつてのようにMac系の雑誌が面白い時代がまたこないかな、こないだろうな。

MACPOWER 2009 Vol.1 (アスキームック)
MACPOWER 2009 Vol.1 (アスキームック) マックパワー編集部

アスキー・メディアワークス 2009-03-17
売り上げランキング : 10531

Amazonで詳しく見る by G-Tools

コンテンツの配信