实现安全nullptr

时间:2012-12-02 23:36:39

标签: c++ c++11 override final nullptr

我希望我的代码可以保留在遗留C ++(使用“NULL”的C ++代码)和新的C ++ 11标准(使用“nullptr”的C ++代码)上

我正在使用GCC,但是当我完成最重要的事情时,还计划为VS重新编译整个代码库。

我是否应该期待GCC和VS都会做类似

的事情
#define NULL nullptr

或者我自己会做得更好(当然使用不同的名称,其中MY_LIB将被我的库后缀替换)?

#ifndef nullptr
    #define MY_LIB_NULL NULL
#else
    #define MY_LIB_NULL nullptr
#endif

我想要实现的是编译的代码,无论C ++ 11的功能是否已经实现(并且由于我没有使用模板,因此很少有)。

例如关键字“覆盖”和“最终”已经完成。

MY_LIB_OVERRIDE //macro, defines to "override" if c++11 is present.
MY_LIB_FINAL    //macro, defines to "final" if c++11 is present.

我问这个问题是因为我知道“nullptr”问题有点奇怪,所以也许只是我已经为覆盖和最终做了同样的事情,这是错误的。需要对此提出意见。任何帮助都很好。

3 个答案:

答案 0 :(得分:2)

您可以通过以下方式创建my_nullptr类型的“false”my_nullptr_t

const class my_nullptr_t
{
    public:

        /* Return 0 for any class pointer */
        template<typename T>
        operator T*() const
        {
            return 0;
        }

        /* Return 0 for any member pointer */
        template<typename T, typename U>
        operator T U::*() const
        {
            return 0;
        }

        /* Safe boolean conversion */
        operator void*() const
        {
            return 0;
        }

    private:

        /* Not allowed to get the address */
        void operator&() const;

} my_nullptr = {};

这适用于C ++ 03和C ++ 11,并且应始终是安全的,无论哪种C ++ 11功能都实现。该解决方案实际上已经在this topic中讨论过,它基于the Official proposal提出了nullptr_t版本。

答案 1 :(得分:1)

NULL是一个扩展为空指针常量的宏。它仍然像以前一样工作。必须与非C ++ 11编译器一起使用的代码应使用NULL

答案 2 :(得分:0)

我认为以下方法有效:

#include <cstddef>

#ifndef MY_LIB_NULL
    #ifndef NULL //check for NULL
        #define MY_LIB_NULL nullptr
    #else
        #define MY_LIB_NULL NULL ///use NULL if present
    #endif
#endif

基本上我检查“NULL”。这是一个宏,可以检查,直到编译器附带该宏(可能是),而不是使用宏有效,当编译器只提供“nullptr”而不再有NULL时,则使用nullptr(可能在遥远的未来,但似乎我们可以愉快地继续使用NULL!)

我认为这比重新定义“nullptr”更安全(就像大多数人想做的那样)