DATE : 2006/10/23 (Mon)
BREW API 3.1 には、デバッグ情報を出力するためのマクロ関数 DBGPRINTF (AEEStdLib.h) があります。使用法は printf と同じなのですが、printf と違って浮動小数点数を出力できません。つまり、次のようにして浮動小数点数を出力してみようとしても、うまくいきません。
DBGPRINTF("%f", 0.23);
そこで、浮動小数点数をいったんワイド文字列に変換してから、DBGPRINTF を適用します。
浮動小数点をワイド文字列に変換するには、マクロ関数 FLOATTOWSTR (AEEStdLib.h) を使用します。
具体的には、次のようになります。
AECHAR string[10]; FLOATTOWSTR(0.23, string, 10);
BREW 用のワイド文字 AECHAR 型の配列を用意して、その中に 0.23 の文字列表現を入れています。
後は、この文字列表現を DBGPRINTF で出力すれば完了です。なお、AECHAR からなる文字列は、「%S」で出力できます。
DBGPRINTF("%S", string);PR
DATE : 2006/10/22 (Sun)
Java では、throw 文を使って例外を投げることができます。(例では、NullPointerException を投げています)
throw new NullPointerException();
そして、catch 文で例外をキャッチできます。(例では、function メソッドで発生する NullPointerException をキャッチします)
try { function(); } catch (NullPointerException e) { // 例外用の処理 }
C++ にも例外機構があります。Java の場合は java.lang.Throwable を継承しているクラスのみ投げることができますが、C++ の場合はどのような型でも例外オブジェクトとして送出することができます。
例えば、次のコードは、例外オブジェクトとして int 型の1を送出します。
throw 1;
この例外を受け取るコードを書くと、次のようになります。この例では、function 関数の中に上の throw 文があるものと仮定しています。
try { function(); } catch (int e) { // 例外用の処理 }
受け取った値を使用しない場合は、変数名(上の例では「e」)を省略できます。
オブジェクトを送出することもできます。
try { throw Object(); } catch (Object& e) { // 例外用の処理 }
ここで、Object オブジェクトは new で生成しないようにします。new で生成してしまうと、生成したオブジェクトを解放し忘れてしまう場合があります。
また、受け取るときは参照で受け取るようにします。
なお、catch 文を複数連ねると、複数の例外に対応できます。つまり、投げられた例外に応じた catch 文が呼び出されます。
ちなみに、次のようにすると、どのような型でも受け取ることができます。
try { function(); } catch(...) { // 例外用の処理 }
(;^ω^)Java の catch(Exception e) { } のようなものですね
なお、catch 文の中で次のように throw 文を記述すると、受け取ったものと同じ例外を送出することができます。
try { function(); } catch(int e) { // 例外用の処理 throw; }
(;^ω^)Java の場合は、catch (Exception e) { throw e; } ですね。
なお、例外機構によって呼び出し元の関数に戻っていく過程では、スタックが次々と巻き戻されていきます。その際、スタック上に確保されていたオブジェクトは解放されますが、ヒープ上に確保されていたオブジェクトは解放されません。そのため、呼び出し元に戻る過程にあるヒープ上のオブジェクトは、上の方法を使って解放するようにします。
Object* obj = new Object(); try { function(); } catch(...) { // 受け取った例外は呼び出し元に投げる delete obj; throw; }
なお、標準 C++ ライブラリには、std::exception という、例外を表すオブジェクトがあります。
(;^ω^)こちらは、Java の Exception (RuntimeException)クラスのような働きをしてくれます。ちなみに、Java のような finally 文はありません。また、チェック例外もありません。
参考文献
DATE : 2006/10/18 (Wed)
風邪気味でふらふらしていた私は、帰りの電車の中で熟睡していました。
そして、ふと目を覚ますと、窓の外には見慣れた光景が……
( ゚д゚)ハッ! 着いたか!
と思って慌てて外へ出てみると……
(;´Д`)かなり前の駅でした。
しかも、ちょうど電車が出てしまい、乗り直すこともできず……orz
夜風がしみる中、十数分間、次の電車を待つはめになりました orz
(;^ω^)風邪がさらに悪化したような気がします
DATE : 2006/10/16 (Mon)
C++ には、使用目的に応じた4種類のキャストがあります。
加えて C 言語形式のキャストも使用できますが、キャストの使用目的が不明瞭になるため推奨されていません。
C++ のキャストは以下の種類に分かれています。
- static_cast
- reinterpret_cast
- const_cast
- dynamic_cast
static_cast を例にとると、次のように使用します。
double d = 2.5; int i = static_cast<int>(d);
「<>」の間にキャスト先の型を入れ、「()」内にキャスト対象の値などを入れます。
以下に使い方を簡単にまとめます。
- static_cast
- 暗黙の型変換が存在する場合に使用するキャストです。例えば、int と double 間や継承関係を持つクラス間のポインタ、参照に使用できます。また、void 型ポインタから具体的な型のポインタへ、int 値から列挙型への変換にも使用できます。
- reinterpret_cast
- 型だけを単純に変更し、内部のビット列は変更しない場合に使用するキャストです。具体的には、ポインタ型同士の変換に使用します。
- const_cast
- ポインタや参照の const 修飾子、volatile 修飾子を外すためのキャストです。
- dynamic_cast
- 仮想関数のある継承関係を持つクラス間のポインタ、参照の型変換を動的に行うためのキャストです。 static_cast とは違い、型変換が行えない場合はキャストの結果が0(ヌル)となります(参照の型変換の場合は、std::bad_cast 例外が発生します)。なお、基底クラスに仮想関数がない場合は、dynamic_cast は使えません。
参考文献
DATE : 2006/10/14 (Sat)
(前回の記事)
テストケースの基本
テストケースは、CppUnit::TestCase(UnitTestCase.h)を継承したクラスに記述します。
また、次のメンバ関数をオーバーロードします。
- void setUp()
- テストケースが実行されると呼び出される関数です。この関数で、このテストケース全体の準備を行います。なお、省略可能です。
- void runTest()
- setUp メンバ関数による準備が終わると呼び出される関数です。実際のテストは、この関数に記述します。しかし実際は、テスト要素ごとに作ったメンバ関数を runTest から呼び出す形になると思います。
- void tearDown()
- runTest メンバ関数が終わると呼び出される関数です。この関数で、テストケース全体の始末を行います。setUp と同様に、省略可能です。
なお、他にも、テストケースに名前をつけるためのコンストラクタなどもありますが、ここでは省略します。
それぞれのテストでは、テスト対象クラスの public / protected メンバ関数からの結果と想定した結果との比較を行うことで、正しく処理を行ったかどうかを確かめます。比較には、次のマクロ関数を使用します。
- ASSERT_EQUALS(想定, 実際)
- 想定した値と実際の値とが等しい(==)かどうか比較します。
- ASSERT_EQUALS_DELTA(想定, 実際, 誤差)
- 上のものと同じですが、誤差を定めることができます。
- ASSERT_EQUALS_OBJ(想定, 実際)
- オブジェクト同士が同じもの(==)かどうか比較します。
- ASSERT_TRUE(実際)
- 実際の結果が真かどうかを確かめます。ただし、引数に渡せるのは bool 型です。BREW で真偽を表す boolean 型は、ASSERT_EQUALS で比較します。
- ASSERT_NULL(実際)
- 実際の結果がヌルであることを確かめます。
- ASSERT_NOT_NULL(実際)
- 実際の結果がヌルではないことを確かめます。
- FAIL_MSG(文字列)
- このマクロが実行されると、テストは必ず失敗します。到達してはならない部分にこのマクロを記述します。失敗した際のメッセージとして、文字列を渡すことができます。
なお、ASSERT_* のそれぞれには、失敗時にメッセージを表示するためのマクロもあります。ただし、ここでは省略します。
(づづきます)