0

私が持っている場合:

Class MyClass {
public:
    MyClass( /* args */ );
private:
    someType member0;
    someType member1;
    // ...
    someType memberN;
#if defined(FIRST_COMPILE_CONDITION)
    someType condition1Member0;
    someType condition1Member1;
    // ...
    someType condition1MemberN;
#endif
#if defined(SECOND_COMPILE_CONDITION)
    someType condition2Member0;
    someType condition2Member1;
    // ...
    someType condition2MemberN;
#endif
};

いくつかの任意の数のコンパイル条件について、永続的なメンバーを最後に配置せずに、これと同等のことを行うクリーンな方法はありますか (特に複数のコンパイル条件の場合)。

MyClass::MyClass( /* args */ ) :
    member0( someValue ),
    member1( someValue ),
    // ...
    memberN( someValue ),
#if defined(FIRST_COMPILE_CONDITION)
    condition1Member0( someValue ),
    condition1Member1( someValue ),
    // ...
    condition1MemberN( someValue ),
#endif
#if defined(SECOND_COMPILE_CONDITION)
    condition2Member0( someValue ),
    condition2Member1( someValue ),
    // ...
    condition2MemberN( someValue ),
#endif
// ...
{
}

上記は、末尾のコンマが原因でほとんどの条件下でコンパイルされないためです。

明確にするために編集します。

someValueは、使用されるそれぞれのケースでコンストラクターの引数に依存する場合と依存しない場合がある、潜在的に独立した任意の値であることを意図していることに、おそらく明示的に注意する必要があります。

4

6 に答える 6

3

初期化子の前にコンマを置くことができます:

MyClass::MyClass() :
     member0( someValue )
    ,member1( someValue )
    // ...
    , memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
    ,condition1Member0( someValue )
    ,condition1Member1( someValue )
    // ...
    ,condition1MemberN( someValue )
#endif
// ...
{
}
于 2012-09-12T19:54:29.567 に答える
2

個人的には、コンパイラ ディレクティブは (インクルード ガードを除いて) できるだけ避けるようにしています。これは通常、問題を隠し、設計上の問題を反映するためです。

私たちが直面する設計上の問題の 1 つは、windows/linux/mac 固有のコードです。クロスプラットフォームを処理する方法はほとんどありません。

これを処理するために、コンパイラ ディレクティブをスキップし、Makefile/プロジェクト レベルで対処します (ツールによって異なります)。ここでそれを行うには、次のようにします。

  1. init_conditional() メソッドをクラスに追加し、コンストラクターで呼び出します
  2. 条件ごとに class_init_....cpp ファイルを追加します。それぞれに init_conditional() の実装が異なります。
  3. コンパイルしてリンクするものを make ファイルに決定させる

さて、それを行うのはそれ自体の作業ですが、コードでははるかにクリーンです。

注: これはメンバーごとの初期化の保護を失いますが、複数条件付きコンパイルの問題に対するより一般的な解決策です。

于 2012-09-12T19:56:41.467 に答える
1

私は常に次の方法で初期化を記述します。

MyClass::MyClass()
  : member0 ( some_value0 )
  , member1 ( some_value1 )
// etc
{}

コンマはメンバーを次のメンバーではなく、そののメンバーから分離するため、論理的により正しい方法です。

于 2012-09-12T20:12:18.077 に答える
0

これが、末尾のコンマを次のエントリの前に移動する人がいる理由だと思います。

member0( someValue ),
    member1( someValue )
    // ...
    , memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
    , condition1Member0( someValue )
    , condition1Member1( someValue )

しかし、それは信じられないほど醜いです。

于 2012-09-12T19:55:01.967 に答える
0

C++11 を使用できる、または使用できるようになると、非常に簡単になります

Class MyClass {
  public:
    MyClass();
  private:
    someType member0 = someValue;
    someType member1 = someValue;
    // ...
    someType memberN;
#if defined(FIRST_COMPILE_CONDITION)
    someType condition1Member0 = someValue;
    someType condition1Member1 = someValue;
    // ...
    someType condition1MemberN = someValue;
#endif
#if defined(SECOND_COMPILE_CONDITION)
    someType condition2Member0 = someValue;
    someType condition2Member1 = someValue;
    // ...
    someType condition2MemberN = someValue;
#endif
};

本当の大きな利点は、複数のコンストラクターを気にする必要がないことです。ただし、他のアプローチでもこれを実現できます。

于 2012-09-12T19:57:05.927 に答える
0

コンマロジックを逆にするだけです:

MyClass::MyClass() :
    member0( someValue ),
    member1( someValue ),
    // ...
    memberN( someValue )
#if defined(FIRST_COMPILE_CONDITION)
    ,condition1Member0( someValue )
    ,condition1Member1( someValue )
    // ...
    ,condition1MemberN( someValue )
#endif
#if defined(SECOND_COMPILE_CONDITION)
    ,condition2Member0( someValue )
    ,condition2Member1( someValue )
    // ...
    ,condition2MemberN( someValue )
#endif
// ...
{
}

最初の memberN の後のコンマの削除に注意してください

于 2012-09-12T19:57:23.977 に答える