2009-03-17 17 views
0

マクロのある場所(ある場合)の詳細を理解しようとしています C++とVisual C++、またWindowsプログラミングライブラリを参照してください。それらを使用せずに解決できないこれらの状況で解決するか?マクロとVisual C++

this blog postからマクロのWTL(その他のもの)を使用していることを読んで覚えていて、MFCでも使用されています。ここでは、そのブログ記事のマクロの例を示します。可能であれば詳細の量は:

// CWindowImpl 
BEGIN_MSG_MAP(Edit) 
    MSG_WM_CHAR(OnChar) 
    MSG_WM_CONTEXTMENU(OnContextMenu) 
    MSG_WM_COPY(OnCopy) 
    MSG_WM_CUT(OnCut) 
    MESSAGE_HANDLER_EX(WM_IME_COMPOSITION, OnImeComposition) 
    MSG_WM_KEYDOWN(OnKeyDown) 
    MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) 
    MSG_WM_LBUTTONDOWN(OnLButtonDown) 
    MSG_WM_LBUTTONUP(OnLButtonUp) 
    MSG_WM_MBUTTONDOWN(OnNonLButtonDown) 
    MSG_WM_MOUSEMOVE(OnMouseMove) 
    MSG_WM_MOUSELEAVE(OnMouseLeave) 
    MSG_WM_NCCALCSIZE(OnNCCalcSize) 
    MSG_WM_NCPAINT(OnNCPaint) 
    MSG_WM_RBUTTONDOWN(OnNonLButtonDown) 
    MSG_WM_PASTE(OnPaste) 
    MSG_WM_SYSCHAR(OnSysChar) // WM_SYSxxx == WM_xxx with ALT down 
    MSG_WM_SYSKEYDOWN(OnKeyDown) 
END_MSG_MAP() 

私は、MSDNのマクロをどうするthesearticlesを読んだだけでなく、書き込みやマクロを回避し、ここで、/ときにそれらを使用するためのベストプラクティスをピックアップしようとしています。

+0

すべてのお返事ありがとうございます。以下の3つの回答すべてに「回答」が広がっています。これはおそらく断片化した質問の結果です。彼が最初に答えたようにジェファファンのポストを答えとしてマークし、MSG_WM_ *の動作について説明しました。 –

答えて

3

これらのマクロはすべてパブリックsdkヘッダーファイルで定義されていますので、必要に応じて自分が行ったことを読むことができます。基本的にここではマクロを使ってWndProc関数を生成しています。各MSG_WM_ *エントリは、wParamとlParamからの引数を元の型に変換し、それらの型を引数として取るヘルパー関数を呼び出すことで、指定されたウィンドウメッセージを処理するcase文です(適切な場合は、いくつかのウィンドウメッセージには0または1つの引数があります)。

私の意見では、これはすべて駄目です。あなたはボイラープレートの束を前に書く必要はないが、それと引き換えに後でデバッグするのはずっと難しくなる。マクロは、定義されているかどうかをチェックする以外に、私の現代プログラミングの世界ではあまり意味がありません。フロー制御を行うマクロ、または特定のローカル変数が常に定義されていると仮定すると、私はかなり不幸になります。特に私はそれらをデバッグする必要があります。

+0

ありがとう:私は現代のC++でマクロを避けるべきであると聞いています。私は間違いなく同意します。私はまだレガシーコードを読むために何が起こっているのか理解したいと思います - パブリックSDKヘッダーファイルを表示するためのリンクがありますか? –

+0

ボイラープレートコードのウィンドウプロシージャーのようなマクロは、実際には本当の意味です。何度も何度も何度も繰り返されているコードで、決して変更する必要はありません。最良の解決策は、ウィンドウプロシージャのためのDSLを含むだろうが、これが欠けている、これらは良いです –

+0

省エネは良いですが、これに微妙にあります。たとえば、基本クラスの実装を呼び出す必要があるときや、それを呼び出す方法さえも初心者には明らかではありません。これらの種類の非常に複雑なマクロは、見つけにくいバグにつながります。時間と場所がある、私はそれを許可します。 –

1

(質問は一種の断片化されているが、Windowsの一部を無視して):

X-Macrosは、コードの重複を避けるためにプリプロセッサを使用しています。

+0

ありがとう:興味深いのは、2001年の記事であり、60年代のアセンブリ言語プログラマーが使ったテクニックです。この記事で概説されているXマクロパターンは、2009年のC++での使用にはまだ関連していますか?推奨されていますか? –

+0

C++は2001年以来実際のメタ言語を育てていないので、技術は依然として非常に重要です。彼らは私の職場で定期的に使用され、コードを清潔で保守しやすいものにしています。それらは、C++内で完全にコードを自動的に生成するいくつかの正気な方法の1つです。 –

+0

チャーリー・マーティンの言うところによると、このテクニックは必ずしもいいものではありませんが、それはすべて相対的なものです.C++のいくつかの問題を解決するのが一番いい方法です。 (C++は実際には3つのシンタックス・イン・-1:毎日のコード、テンプレート、プリプロセッサです。) –

3

Peter、viやEMACSが優れたエディタであるかどうか尋ねるかもしれません。 (EMACS、ところで)Cプリプロセッサは恐ろしいアイデアだと思う人がたくさんいます。 StroustrupとJim Goslingが参加しています。そのため、Javaにはプリプロセッサがなく、プリプロセッサの使用を避けるために、constからC++に入れた無数のStroustrupがあります。

このコードのように、新しい言語を追加することが便利な人がいます。

あなたは、元のBourneシェルコードを読めば、あなたはそれが基本的に(そして、本当にクールな言語であることという。)それをAlgol68のような外観を与えるために、マクロを使用

IF a == b THEN 
    do_something(); 
    do_more(); 
ELSE 
    do_less(); 
FI 

スティーブ・ボーンのように見える見つけることができますスティーブ・ボーン以外の人と一緒に働くことは非常に難しいかもしれません。

次に、最も驚くべき難読化のいくつかが#defineを利用する難読化Cコンテストを見てください。

個人的には、あまりにも気にしませんが、その例は少し難しいです(どのようにデバッグしますか?)しかし、そのようなことはネットなしでも機能しています。そこには多くのWallendasがありません。

+0

ありがとう:言語内の言語は考えるのに良い方法です。あなたが使っている「良い」マクロやマクロの例がありますか? –

+0

私が本当に気に入りました*複雑なマクロの使用は考えられません。時には、Linuxカーネルのマクロのように、カーネル内のループがヒットする*理由があります。上記の例のように、DSLを実装することもあります。 –

+0

おそらく私が今までにやった中で最も複雑なマクロは、log4jのようなものをCのために実装するマクロをロギングすることでした。 –