正确在 C++ 头文件/实现文件中放置 #undef 指令

LCs*_*Csa 1 c++ c-preprocessor

我正在编写一个类(在头文件myClass.h和实现文件中分开myClass.cpp),我想将它与标准 C++ 和 Qt 框架一起使用。由于代码中的差异非常小(我想尝试一次),我决定#define USINGQT 1通过

#if USINGQT==1
    //Qt code
#else
    //standard code
#endif
Run Code Online (Sandbox Code Playgroud)

现在我得出的结论是,在“激活”开关时QString在整个班级中使用s 而不是std::strings会很方便USINGQT。但是,上面的方法会使代码变得非常混乱。我的解决方案(在头文件中):

#if USINGQT==1
    #include <QString>
    #define string QString
#else
    #include <string>
    #define string std::string
#endif
Run Code Online (Sandbox Code Playgroud)

现在问题来了:

考虑文件的样子

---myclass.h-------------------------
#ifndef MYCLASS_H
#define MYCLASS_H

#define USINGQT 1  //1=on, else off
#if USINGQT==1
    #include <QString>
    #define string QString
#else
    #include <string>
    #define string std::string
#endif

namespace mySpace {

class MyClass {
    string qtOrStd;
    string foo();
    //etc...
};

} //namespace
#endif //MYCLASS_H
-------------------------------------

---myclass.cpp-----------------------
#include "myclass.h"
using namespace mySpace;

//implementations
string MyClass::foo()   //string symbol occurs, as does the USINGQT
-------------------------------------
Run Code Online (Sandbox Code Playgroud)
  1. 哪里是正确的地方#undef的string和USINGQT符号?在头文件的末尾(然后在实现文件中也需要重新定义和“取消定义”)还是只是在实现文件的末尾?

  2. 我也应该将string宏大写,我不应该......?>.>

  3. 如果我将宏定义放在命名空间中,我会收到大约。800 条错误消息,其中包含“no member of mySpace::std”等条目。你能在没有更多信息的情况下说些什么吗?否则它编译得很好。


编辑:我可能应该告诉你我希望宏只适用于这个特定的头文件及其实现文件。尽管我当然会选择typedefs - 在宏的情况下,我猜我应该将 放在#undef实现文件的末尾。因为宏不会因为包含守卫而被重新定义。

sil*_*asp 5

  1. 首先,您不需要USINGQT通过使其等于 1来切换,您可以简单地#define USINGQT然后将其#ifdef USINGQT用于 if 语句。
  2. 就您切换使用哪个字符串库的能力而言,我建议在预处理器 if 语句旁边使用 typedef。这将避免任何命名空间问题。下面显示了一个示例。

// -------------- 一些配置文件 -------------=

#define USINGQT

// -------------- MyClass.h --------------------=
// Header guard
#ifndef MyClass
#define MyClass 

// Conditional Header types
#ifdef USINGQT
// QT OPTION
typedef QString my_string;

#else
//  Not QT
typedef std::string my_string;
#endif

class MyClass {
public:
    my_string some_string;

    MyClass()
    {
        my_string = "hello world";
    }
};
#endif
Run Code Online (Sandbox Code Playgroud)