『Symbian OS C++ 実践開発技法』読書メモ (2005-06-30)
Symbian OSについて日本語で書かれた情報源は非常に少ないわけですが、そんな中『Symbian OS C++ 実践開発技法』という書籍が発売されました。とりあえず、流し読みして気づいたことなどをメモ。
CBaseクラスの定義について(p.6)
e32base.hを見ると、CBaseがコピーコンストラクタと代入演算子をprivate宣言していることが分かる。これは、クラスのクライアントが、間違ってそのクラスのオブジェクトの浅いコピーを作ったり、そのオブジェクトに代入したりするのを防止する手段として、一般に使われているものだ。
このテクニック自体は『Effective C++』にも載っている有名なものですが、大元のCBaseクラスでこれをやっているとは知らなかった。今までわざわざ自前でprivate宣言していました。
書き換え可能な静的データ(p.253)
以前の記事「Symbian C++開発・DLL内のstatic変数(2005-04-01)」に書いたこととほぼ同様の内容。やはり誰もがはまる落とし穴なのでしょうか。
(余談ですが、このサイトのアクセスログを見ると、"ERROR Dll has initialised data"といった検索ワードで検索している方がちらほら見受けられます)
便利なASSERT定義(p.299)
#ifdef _DEBUG #ifdef ASSERT #undef ASSERT #endif #define __ASSERT_FILE__(s) _LIT(KPanicFileName, s) _LIT(KPanicFileName,s) #define __ASSERT_PANIC__(l) User::Panic(KPanicFileName().Right(12),l) #define ASSERT(x) { __ASSERT_FILE__(__FILE__); __ASSERT_DEBUG(x, __ASSERT_PANIC__(__LINE__) ); } #endif
このASSERTを使うと、パニックカテゴリ文字列が「ソースファイル名(の末尾12文字)」で、パニック番号が「(ひっかかったASSERTが存在する)行番号」のパニックを発生します。要は「ソースファイル名と行番号が表示されるASSERT」というわけです。「便利」といっても、他環境での一般的なASSERTでは当たり前のことではありますが……。
なお、上記のコードは本に記述されている内容をそのまま引用したものですが、ASSERTマクロの中身がマルチステートメントになっているのはまずいのではないかという気がします。例えば、以下のようなケースでコンパイルエラーになってしまいそうです。
if (...) ASSERT(...); else ...
ちなみに、私の場合はこんな感じのASSERTマクロを使っています。
#define WIDE_LIT(lit) L ## lit // 文字列リテラルをワイド文字にする #define WIDE_MACRO(macro) WIDE_LIT(macro) // 文字列マクロをワイド文字にする #define MY_ASSERT(exp) __ASSERT_DEBUG(exp, \ User::Panic(_L("" WIDE_MACRO(__FILE__)).Right(16), static_cast<TInt>(__LINE__)));
ワイド文字がらみでプリプロセッサでいろいろ小細工をしていますが、やっていることは似たようなものです。