gl5_progのメモ

自分のためのメモとかまとめとか

外からメンバ変数を定義する方法

問題

とあるクラス/構造体にメンバ変数を定義したいとします。しかし、様々な事情によりクラス定義内の書き換えができない場合どうしたらよいでしょうか。状況的には以下のようになります。

http://ideone.com/jHqwio
prog.cpp

#ifndef HEADER_H
#define HEADER_H

//------------------------------------
// この位置でstruct Aのメンバとして
// int m_SecretMember;を追加せよ。
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//------------------------------------

struct A
{
    int m_Value;
};

int main( void )
{
    A a;
    a.m_SecretMember = 1;
    return 0;
}

#endif

ideoneは単一ファイルしか扱えないので、prog.cppをヘッダーだと思ってください。 コメントにあるように、struct Aの外でint m_SecretMember;を定義したいのです。どうしたらよいでしょうか。

正解

http://ideone.com/iFUoar

#ifndef HEADER_H_1
    #define HEADER_H_1
    #define m_Value m_Value; int m_SecretMember
    #include "prog.cpp"
    #undef m_Value
    #define HEADER_H_END
#endif
#elif !defined(HEADER_H_END)

ポイント

  • m_Value を m_Value; int m_SecretMember に置き換えるマクロとして定義
  • 定義したマクロm_Value を ファイルの最後にundefするために自己インクルード
  • 自己インクルード時に無限インクルードにならないように、新たにインクルードガードHEADER_H_1を定義
  • インクルードガードHEADER_Hに対応する#elifを追加することで、#elif以降が自己インクルード時のみ展開されるようにする(多重インクルードガードにもなる)

おわり

ANTLR C Targetで必要にかられて考えたけど、実はこんなことする必要がないと判明。頭も混乱するしこんなことは止めておこう。