2

クラスにたくさんのメンバーを追加する必要があります。次のようなマクロを追加したいと思います。

#define MEMBER(TYPE,NAME) \
    private: TYPE m_##NAME; \
    public: TYPE get##NAME() const { return m_##NAME; } \
    public: void set##NAME(TYPE in##NAME) { m_##NAME = in##NAME; }

次に、それを使用してメンバーをクラスに追加します。

class foo {
    MEMBER(std::string, OutputDir);
    MEMBER(int, MaxIterations);
    MEMBER(double, OptimizationCutoff);
    // And a couple dozen more members...
    public:
    // The rest of the class declarations
};

意図は明らかに、このようなコードの複数のインスタンスをショートカットすることです。多数のクラスメンバーごとに3行です。

private: std::string m_OutputDir;
public: std::string getOutputDir() const { return m_OutputDir; }
public: void setOutputDir(std::string inOutputDir) { m_OutputDir = inOutputDir; }

そのようなコーディングに対する考慮事項はありますか?

4

1 に答える 1

4

まず、私は観察を指摘したいと思います。ここで定義したマクロはまったく役に立たないようです。私はあなたがやろうとしていることを理解しています.1行のコードで、メンバー変数と単純なgetterおよびsetterメソッドを宣言しています。

私は反論します:これらのメンバー変数を単純なゲッターとセッターで公開しているだけなら、メンバー変数publicを作成してそれで完了しないのはなぜですか?

そのようなコーディングに対する考慮事項はありますか?

はい、マクロの邪悪な誤用に関するすべての通常の懸念。ここに関連するいくつかを見てみましょう。

あなただけが知っている秘密の言語を作成しています。

次のようなコード:

class foo {
    MEMBER(std::string, OutputDir);
    MEMBER(int, MaxIterations);
    MEMBER(double, OptimizationCutoff);
    // And a couple dozen more members...
    public:
    // The rest of the class declarations
};

一見すると、その構造はある程度foo明白かもしれませんが、メンバーの 1 つ、またはマクロ自体を維持または拡張する際には、多くの詳細が不明瞭になります。

たとえば、これをちらりと見ただけで member を宣言しているように見えますがOutputDir、それがデータ メンバーなのかメンバー関数なのかは実際には示されていません。メンバー関数の場合、戻り値の型は何ですか? パラメータは何ですか?メンバー関数テンプレートを宣言するにはどうすればよいですか? テンプレート パラメータとは何ですか?

最初にコードを入力するときは 1、2 回のキーストロークを節約できる構文をここで作成しましたが、これらの質問のいずれかに対する回答が必要な場合は、何時間ものフラストレーションとヘッドバンギングが発生する可能性があります。あなた以外の誰も文書化もサポートもしていないので、あなたのマクロはあなただけが知っている秘密の言語のようなものになってしまいます。

マクロはデバッグが難しい

マクロを使用するコードをデバッグすると、マクロやその呼び出し方法ではなく、置換されたテキストが表示されます。これは非常に混乱する可能性があります。

マクロには名前空間がありません

マクロは力ずくのテキスト置換ツールです。それらは名前空間やスコープを尊重せず、定義および呼び出されるすべての場所に普遍的に適用されます。これにより、C++ 型システムが完全に回避され、そうでなければエラーを引き起こすコードを記述できるようになります。

マクロには、奇妙で意図しない副作用があり、予期しない場所に適用されます。

一般的な例は、 VisualStudio によるminandマクロの定義です。これにより、標準ライブラリ内の同じ名前の関数が上書きされます。max副作用は奇妙なものになる可能性があり、前述のようにデバッグが非常に困難です。

于 2013-10-18T19:26:55.267 に答える