Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C+中放置#unde指令是正确的+;标题/实现文件 我正在编写一个类(在头文件中分离了代码> MyCase.H./Cube和实现文件 MyCalp.CPP >,我想使用标准C++和QT框架。由于代码之间的差异非常小(我想尝试一下),因此我决定使用qt 1来定义,以便通过 #if USINGQT==1 //Qt code #else //standard code #endif_C++_C Preprocessor - Fatal编程技术网

在C+中放置#unde指令是正确的+;标题/实现文件 我正在编写一个类(在头文件中分离了代码> MyCase.H./Cube和实现文件 MyCalp.CPP >,我想使用标准C++和QT框架。由于代码之间的差异非常小(我想尝试一下),因此我决定使用qt 1来定义,以便通过 #if USINGQT==1 //Qt code #else //standard code #endif

在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

现在我得出的结论是,当使用qt开关“激活”
时,在整个类中使用
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