-5

我有各种类Case0, Case1,Case2等,我想使用一些预处理器在它们之间切换#define。它们都共享相同的接口(相同的公共方法),我可以使用 OOP,但我更喜欢使用预处理器指令。

现在我有类似的东西:

#define CASECLASS Case0
//#define CASECLASS Case1
//#define CASECLASS Case2

#define CASE 0

class Main {
public:
   CASECLASS *mycase;

   Main() {

       mycase = new CASECLASS();

       if(CASE==0) {
           mycase->foo();
           // something else
       }
       if(CASE==1) {
           mycase->foo();
           // something else
       }
   }
}

这样,每次我必须切换时,我都必须更改定义CASECLASSCASE. 我想知道是否有更清洁的方法。

编辑:

我不想使用 OOP,因为不同的类使用不同的库。这会影响编译时间,并且它们是平台相关的。我认为预处理器指令是一个更好的选择。

4

3 回答 3

3

如果它们都共享相同的界面,为什么还需要在它们之间切换?这里有一些更好的想法。

第一个:将预处理器魔法放在一个地方。把它放在标题中:

#if defined(PLATFORM_ONE)
#include "platform_one/implementation.hpp"
typedef PlatformOneImplementation TheClass;
#elif defined(PLATFORM_TWO)
#include "platform_two/implementation.hpp"
typedef PlatformTwoImplementation TheClass;
#else
#error No implementation available.
#endif

这将是您项目中唯一使用预处理器的地方。其他一切都只使用 TheClass 而没有任何平台依赖。如果它是依赖的,那么实现类应该隐藏它。

并且如前所述,使用项目配置进行切换。

这是一个更好的选择。把它放在标题中:

class TheClass {
public:
  TheClass();
  ~TheClass();
  // Public stuff goes here.
private:
  struct Impl;
  std::unique_ptr<Impl> pimpl;
};

然后每个平台都有一个 .cpp 文件,并使用项目配置只编译正确的一个:

// platform_one/implementation.cpp
struct TheClass::Impl {
  PlatformSpecificStuff stuff;
  MoreStuff more;
};
TheClass::TheClass() : pimpl(new Impl) {}
TheClass::~TheClass() {}
// Implementation of public functions here.

这两个选项都比使用预处理器开关乱扔代码要好得多。

于 2013-07-18T13:06:07.930 回答
1

在这种情况下,我的典型建议是将不同的代码放在不同的源文件中,并使用您的构建工具来选择在构建时构建哪些源文件。

你当然可以让它与预处理器技巧一起工作。但是预处理器是一种容易出错的额外语言 hack,它会使您的源代码更难阅读和维护。最好尽可能避免使用它。

于 2013-07-18T13:11:23.037 回答
0

以下代码必须有效:

    #ifdef CASE1
    class1
    {
    };
    #endif

    #ifdef CASE2
    class2
    {
    };
    #endif

    #ifdef CASE3
    class3
    {
    };
    #endif

并使用Project Configurations

于 2013-07-18T12:31:55.747 回答