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

就个人而言,我尽量避免使用编译器指令(包括守卫除外),因为它们通常隐藏问题并反映设计问题。

我们都面临的一个设计问题是 windows/linux/mac 特定代码。处理跨平台的方法很少。

为了处理这个问题,我跳过编译器指令并在 Makefile/project 级别解决它(取决于您的工具)。为此,您可以:

  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
// ...
{
}

注意删除第一个成员N之后的逗号

于 2012-09-12T19:57:23.977 回答