在C+中放置#unde指令是正确的+;标题/实现文件 我正在编写一个类(在头文件中分离了代码> MyCase.H./Cube和实现文件 MyCalp.CPP >,我想使用标准C++和QT框架。由于代码之间的差异非常小(我想尝试一下),因此我决定使用qt 1来定义,以便通过 #if USINGQT==1 //Qt code #else //standard code #endif
现在我得出的结论是,当使用qt开关“激活”在C+中放置#unde指令是正确的+;标题/实现文件 我正在编写一个类(在头文件中分离了代码> MyCase.H./Cube和实现文件 MyCalp.CPP >,我想使用标准C++和QT框架。由于代码之间的差异非常小(我想尝试一下),因此我决定使用qt 1来定义,以便通过 #if USINGQT==1 //Qt code #else //standard code #endif,c++,c-preprocessor,C++,C Preprocessor,现在我得出的结论是,当使用qt开关“激活”时,在整个类中使用QStrings而不是std::strings会很方便。然而,上面的方法会使代码非常混乱。我的解决方案(在头文件中): #如果使用qt==1 #包括 #定义字符串QString #否则 #包括 #定义字符串std::string #恩迪夫 现在进入问题: 请考虑这些文件的外观 ---myclass.h------------------------- #ifndef MYCLASS_H #define MYCLASS_H #defi
时,在整个类中使用QString
s而不是std::string
s会很方便。然而,上面的方法会使代码非常混乱。我的解决方案(在头文件中):
#如果使用qt==1
#包括
#定义字符串QString
#否则
#包括
#定义字符串std::string
#恩迪夫
现在进入问题:
请考虑这些文件的外观
---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
-------------------------------------
--myclass.h-------------------------
#ifndef MYU H类
#定义MYCLASS_H
#使用qt 1//1=on,else-off定义
#如果使用qt==1
#包括
#定义字符串QString
#否则
#包括
#定义字符串std::string
#恩迪夫
命名空间mySpace{
类MyClass{
字符串qtOrStd;
字符串foo();
//等等。。。
};
}//名称空间
#endif//MYCLASS\u H
-------------------------------------
---myclass.cpp-----------------------
#包括“myclass.h”
使用名称空间mySpace;
//实现
字符串MyClass::foo()//字符串符号出现,USINGQT也出现
-------------------------------------
字符串和使用qt
符号的正确位置在哪里?在头文件的末尾(这也需要在实现文件中进行重新定义和“取消定义”),还是仅仅在实现文件的末尾
我也应该大写字符串
宏,不是吗…?>>
如果我将宏定义放在名称空间中,我会收到大约800条错误消息,其中包括“no member of mySpace::std”等条目。你能不能在没有进一步信息的情况下谈谈这件事?否则它编译得很好
编辑:我可能应该告诉您,我希望宏只应用于这个特定的头及其实现文件。尽管事实上我当然会选择typedef
s,但在宏的情况下,我想,我应该将#unde
放在实现文件的末尾。因为包含保护将不会重新定义宏。除非另一个文件尝试重新定义宏,否则不必取消定义宏。在使用宏之前,不能#取消定义它,因此,如果在头中定义宏并希望在包含头的文件中使用它,则不能#取消定义它
1) 取消定义字符串和使用QT符号的正确位置在哪里?在头文件的末尾
只有在标题中使用它时。。。但是你显然是把它作为一个包含头的文件来使用的,所以没有
还是仅仅在实现文件的末尾
在实现文件末尾取消定义宏是毫无意义的,因为在宏应用到的文件末尾之后将不再有代码。让它保持清晰
2) 我也应该大写字符串宏,不是吗…?>。>
你不必大写宏,但这是惯例。也就是说,用与标准类相同的名称定义宏只是自找麻烦。您应该在此处使用typedef
而不是宏,以便在名称冲突时获得有意义的错误消息。并使用另一个名称,如string\u t
,或在命名空间中定义typedef
3) 如果我将宏定义放在名称空间中,我会收到大约800条错误消息
这些错误并不是在名称空间中定义宏时产生的。错误来自于将宏当作命名空间的一部分使用。例如,如果你说:
namespace mySpace {
#define string std::string
}
mySpace::string s;
然后,string
将被std::string
替换,typename变成mySpace::std::string
。由于您没有在mySpace
中定义std
命名空间,这是错误的。您需要了解的是名称空间对预处理器宏没有任何影响。这使得避免名称冲突变得更加困难,这也是您通常希望避免预处理器宏的原因之一
如果USINGQT
宏应用于您的所有代码,因此它对于所有文件都必须相同,那么您可能根本不想在头中定义它,而是将它作为参数传递给编译器。这样,您就可以轻松地使用不同的值进行编译,而无需更改文件
关于您的编辑:
即使您希望宏在另一个文件中以不同的方式定义,那么在实现结束时取消定义宏也没有效果,因为包含头的文件不会包含实现文件。您应该避免需要宏的多个不同定义(或缺少定义)的情况,但是如果您处于这种情况,那么是的,您唯一的解决方案是在每个需要宏的文件中分别定义它,然后在任何需要宏的头的末尾取消定义。但是您没有遇到这种情况,因为您可以使用类型别名来代替。除非另一个文件尝试重新定义宏,否则您不必取消定义宏。在使用宏之前,不能#取消定义它,因此,如果在头中定义宏并希望在包含头的文件中使用它,则不能#取消定义它
1) 取消定义字符串和使用QT符号的正确位置在哪里?在头文件的末尾
除非你
namespace mySpace {
#define string std::string
}
mySpace::string s;
#define USINGQT
#ifdef USINGQT
#include <QString>
#else
#include <string>
#endif
namespace mySpace {
#ifdef USINGQT
typedef ::QString string;
#else
typedef ::std::string string;
#endif
}
#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