トップ 一覧 検索 ヘルプ RSS ログイン

【C++】文字列リソースのための簡単なラッパークラスの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
{{category 開発情報}}

{{category 陰郎の書いた記事,nolink}}
!!概要
 ここでは、文字列リソースの取得処理を簡略化するためのクラスについてサンプルを示します。

 

!!説明
 まず、以下のような文字列リソースがあるとします。これをプログラム内で読み込んで FrmCustomAlert で使用することを考えましょう。

 STRING ID TSTR_SAMPLE_MESSAGE "God save the Palm!"

 普通に実装すると、以下のようなコードになるかと思われます。

     MemHandle handle;
     const char* pString = NULL;
 
     handle = ::DmGetResource( 'tSTR', TSTR_SAMPLE_MESSAGE );
     pString = static_cast<const char*>( ::MemHandleLock( handle ) );
 
     ::FrmCustomAlert( ALERT_FOO, pString, "", "" );
 
     ::MemHandleUnlock( handle );
     ::DmReleaseResource( handle );

 では、この一連の(面倒な)処理をカプセル化するクラスを考えることにします。目標は、以下のように書くだけで済ませることです。

     StringResource res( TSTR_SAMPLE_MESSAGE );
     ::FrmCustomAlert( ALERT_FOO, res, "", "" );

 これだけの記述で済ませるには、StringResource クラスがどのように実装されている必要があるでしょうか。ポイントは3つです。

*コンストラクタでリソースのオープンからロックまでをしている。
*FrmCustomAlert のパラメータにそのまま渡していることから、const char* 型へのキャスト演算子をオーバーロードしている。
*リソースの開放を明示的にしていないことから、デストラクタでリソースの開放を行っている。

 上記の要件を満たすクラス StringResource の実装例を以下に示します。特に難しい点は無いと思いますが、デストラクタでリソースの開放を行っている関係上、オブジェクトがスコープを外れるまではリソースが開放されない点には注意が必要です。

 class StringResource {
 public:
     StringResource( UInt16 resID ) : m_handle( MemHandle( ) ),
                                      m_pString( NULL ) {
         m_handle = ::DmGetResource( 'tSTR', resID );
         m_pString = static_cast<const char*>( ::MemHandleLock( m_handle ) );
     }
    
     ~StringResource( ) {
         ::MemHandleUnlock( m_handle );
         ::DmReleaseResource( m_handle );
     }
 
 private:
     // intentionally no implementation...
     StringResource( const StringResource& rhs );
     StringResource& operator=( const StringResource& rhs );
 
 public:
     inline operator const char*( ) const {
         return m_pString;
     };
 
 private:
     void* operator new( UInt32 n ) {
         return ::MemPtrNew( n );
     };
     void operator delete( void* p ) {
         ::MemPtrFree( p );
     };
 
 private:
     MemHandle   m_handle;
     const char* m_pString;
 
 };

 また、new / delete 演算子をオーバーロードしているのは、DA で使用した場合、CodeWarrior ではエラーが発生するため、その回避策です。基本的にはスタック上にインスタンスを作成する前提なので、private 指定になっています。代入演算子やコピーコンストラクタが private 宣言だけで実装無しなのはオブジェクトのコピーを禁止にするためです。
 

!!参考情報
 このページで説明したラッパークラスを発展させ、リソース取得処理を汎用化したクラステンプレートを「 [[【C++】 リソースのための汎用クラステンプレート]] 」で説明しています。

 

!!注意事項
 特にとくにありません。

 

!!コメント
※ コメントスパムが来ますので、コメント用フォームを使用不可としました。コメントを記入したい方は、申し訳ありませんが直接入力するか、あるいは編集してコメント用フォームを有効にして入力願います。
//{{comment multi}}