通过具有多重继承的类对nullptr进行upcast

时间:2016-01-27 22:27:49

标签: c++ multiple-inheritance nullptr

问题在于,对具有多重继承的类的第二个超类的nullptr的隐式转换(至少在LLVM 7.0.2中)在调整中应用于nullptr。指针现在不再为null(如果在超类的方法中执行空检查)可能导致崩溃(我猜技术上是未定义的行为)。

这是一个最小的例子:

#include <iostream>

inline bool pointerIsNotNull(const void* ptr) { return ptr != nullptr; }

class IntValue {
    public:
        IntValue() { }
        int getIntValue() { return pointerIsNotNull(this) ? value : 0; }
    private:
        int value;
};

static const char* nullptrChar = "nullptr";

class CharValue {
    public:
        CharValue() { }
        const char* getCharValue() { return pointerIsNotNull(this) ? value : nullptrChar; }
    private:
        char* value;
};

class Foo : public IntValue, public CharValue {
    public:
        Foo() { }
        double getDoubleValue() { return pointerIsNotNull(this) ? value : 0; }
    protected:
        double value;
};

int main(int argc, const char * argv[])
{
    Foo* foo = nullptr;

    std::cout << foo->getIntValue() << std::endl;

    CharValue* charValue = foo;
    std::cout << charValue->getCharValue() << std::endl;

    std::cout << foo->getCharValue() << std::endl;
}

我的问题是: 有没有办法检查这种恶作剧,而无需在调用第二个超类之前手动检查nullptr?

你知道吗,有没有一种优雅的方法可以做到这一点(可能在第二个超类中),这可以向我保证我已经抓住了所有可能出现这种行为的例子?

编辑:是的,我知道从nullptr调用成员函数不是现代实践。我认为(直到我发布这个问题)它曾经被接受的做法,并且在任何情况下我都受到我无法控制的标准的约束。因此,假设在nullptr上调用成员函数将始终输入正确的函数,是否有一个优雅的解决方案来解决我的问题?

1 个答案:

答案 0 :(得分:6)

foo->getIntValue()为空指针时,

foo未定义,这使得整个程序未定义。
也就是说,解除引用本身是未定义的,并且您的程序在到达检查之前就注定了。

检查this是否为空是没有意义的,因为编译器可以自由地假设它不是(如果是,程序将是未定义的,因此编译器可以做任何事情要)。