2011-07-22 8 views
3

私はC++用のツリーベースのデバッグ/ロギングシステムを構築しています。グローバルアドレスでオブジェクトアドレスまたはNULLを取得する統一方法

「ユーザーインターフェイス」は、ユーザー定義のメッセージと呼び出しサイトの情報(ファイル、行、オブジェクトアドレス)を特別な機能に渡し、ログを実行するマクロです。

この関数はオブジェクトアドレスを使用してオブジェクトインスタンスごとにメッセージをグループ化します。

現在のところ、それは次のようになります。私はNULL代わりのthisが定義されていないthisを(取得する(msgマクロで使用可能)何らかの統一的な方法があり、聞きたい

// in logging system header 
#define msg (event_level, message) \ 
    do_logging_ (event_level, __FILE__, __LINE__, this, message) 

... 

// in code 
msg (MSG_WARNING, "some text"); 

グローバル/静的関数)?

+0

(コンパイラが分かる限り)このコードは関数の外に出現することもあります。式は、グローバル変数の初期化子や静的constクラスのメンバのためのクラス内で使用されたときに、グローバルスコープで現れることがあります。 – MSalters

答えて

4

は、あなたのマクロ定義を変更することができます。

#define msg (event_level, message, THIS) \ 
    do_logging_ (event_level, __FILE__, __LINE__, THIS, message) 

使用法:

msg (MSG_WARNING, "some text", this); // in member methods 
msg (MSG_WARNING, "some text", NULL); // otherwise 
+0

また、3つの引数バージョンに 'this'または' NULL'を与える両方のオプションの2つのラッパーマクロを提供することで、呼び出し元サイトの冗長性を削減できます。しかし、外部から与えられたオブジェクト(例えば、「friend」関数)に対してメッセージを発行することはできないので、少しの自由を奪います。しかし、3つの引数を持つバージョンはプライベートにならなければならないという人は誰もいません。 – delnan

+0

@delnan、私はあなたの提案された解決策についても考えていました。しかし、1を超えるとそれは簡単に保たれます。投稿されました。 – iammilind

+0

これは唯一の方法だと思われます...それほど「エレガントな」解決策ではありませんが、とにかく感謝します。 – intelfx

1

私は、これはあなたがログインしたいあなたのクラスにコードを変更することなく可能ではないと思います。追加のグローバル定義

class A : public loggable_class<A> 
    { 
     ... 
    }; 

:たとえば

template <typename T> 
    class loggable_class 
    { 
    protected: 
     T* get_this() { return static_cast <T*> (this); } 
    }; 

:あなたがこれを行うには喜んでいる場合は、しかし、あなたはこのようなテンプレートから機能をログに記録したいすべてのクラスを派生でき関数get_this()は非メンバ関数で使用されます。

inline void* get_this() 
    { 
     return NULL; 
    } 

ログマクロは次のようになります。

#define msg (event_level, message) \ 
     do_logging_ (event_level, __FILE__, __LINE__, get_this(), message) 
+0

公正であるには、メンバ関数で 'dynamic_cast 'を使いたいと思うでしょう。あなたはダイヤモンドの継承と混乱する問題があるかもしれません。 –

+0

私はそれを試しましたが、静的メンバー関数で使用すると、コンパイラは明らかにグローバル 'get_this()'に対して 'loggable_class :: get_this()'を優先しています。そしてオブジェクトなしの呼び出しのために失敗します。 – intelfx

+0

動的キャストをvoid *にすると、ダイナミックキャストの機能が少し失われたことになります。 vtableなしでは、機能的にdynamic_castにすることはできません。 – dascandy

関連する問題