8

私はロギング/トレースユニットに取り組んでいます(そして、既存のものを指さないでください、これは結果と同じくらい経験のためです)。

実行時の呼び出しスタックトレースを取得するにはTraceObject、関数が最初に入力されたときに、現在のクラスと関数の情報を保持するインスタンスを構築するという考え方があります。やや似ています:

TraceObject to( "MyClass", "myClassFunction" );

スレッドごとのスタックをTraceObjectプッシュするコンストラクター、デストラクタはそれを再びポップします。thisしたがって、スタックはコールスタックを照会できます。

私はこれを満足のいくように機能させました。ただし、小さなスニッチがあります:オブジェクトto。設計上、その名前で呼ばれることはありません。したがって、名前を付ける必要はありません少なくとも、クライアントが使用する識別子(または、_プレフィックスの場合は実装)と衝突する可能性のある名前を付ける必要はありません。

tl; dr

スタック上に匿名の非一時オブジェクト(つまり、関数が戻るまで存続するが、識別子を持たないオブジェクト)を作成することは可能ですか?もしそうなら、それはどのように行われますか?

4

3 に答える 3

5

いいえ。

C ++には、式の結果である一時的な匿名オブジェクトがありますが、それらは、それらが含まれているステートメントのコンテキストでのみ存在します。

実際に匿名オブジェクトを宣言しようとすると、パーサーが混乱し、宣言しているように見えます...関数です!


しかし、それでは必要ですか?

マクロを使用して実際にを宣言することに同意する場合はTraceObject、トレースごとにマクロを使用するのと同じくらい簡単です。したがって、そこでクラスと関数を提供します。または同等のものを使用し__func__て、クラス名と関数名(必要な文字列解析のビット、コンパイラによって異なります)を抽出し、そこから作業できます。

そしてもちろん、ファイル名と行番号が必要になる可能性があるため、とにかく各トレースにマクロを使用します。

于 2013-03-20T08:29:35.077 に答える
3

私のコメントで述べているように、スコープが制限された匿名変数は使用できません。

#define BEGIN_LOG   TraceObject abcdefghij( "", __func__ );

void Function(){
    BEGIN_LOG;

    //bla bla

}

クラス名を取得するコンパイラマクロがあれば、これでうまくいくはずです。

編集:クラス名を取得する簡単な方法で運がない、クラス名マクロで提案されているようなことをしなければならないかもしれません。または単にでやります__FILE__

編集:どちらかまたは両方が希望どおりに機能するかどうかを試して確認することをお勧めします__func____FUNCTION__C++標準も指定されていません。

于 2013-03-20T08:21:45.693 に答える
1

いくつかの行番号のもの:

#define XPASTE(arg1, arg2) PASTEX(arg1, arg2)
#define PASTEX(arg1, arg2) arg1 ## arg2
#define TRACELOG() \
            TraceObject XPASTE(trace_object,  __LINE__)
于 2013-03-20T08:42:41.403 に答える