通过具有多重继承的 class 向上转换 nullptr
upcast of nullptr through class with multiple inheritance
问题是 nullptr 的隐式转换到第二个超 class 的 class 具有多重继承结果(至少在 LLVM 7.0.2 中)正在应用的调整到 nullptr。指针现在不再为 null(如果在 super class 的方法中执行 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;
}
我的问题是:
有没有办法在调用第二个 superclass 之前无需手动检查 nullptr 来检查这种恶作剧?
你知道吗,有没有一种优雅的方法可以做到这一点(也许在第二个超级class中)可以让我确信我已经抓住了这种行为的所有可能的例子?
编辑:是的,我知道从 nullptr 调用成员函数不是现代做法。我认为(直到我发布这个问题)它曾经是公认的做法,无论如何我都受到我无法控制的标准的约束。所以,假设在 nullptr 上调用成员函数总是会输入正确的函数,我的问题有没有优雅的解决方案?
当foo
是空指针时,foo->getIntValue()
是未定义的,这使得你的整个程序都未定义。
也就是说,取消引用本身是未定义的,你的程序在到达检查之前就注定要失败。
检查 this
是否为空是没有意义的,因为编译器可以自由地假设它不是(如果是,程序将是未定义的,所以编译器可以做任何它想要)。
问题是 nullptr 的隐式转换到第二个超 class 的 class 具有多重继承结果(至少在 LLVM 7.0.2 中)正在应用的调整到 nullptr。指针现在不再为 null(如果在 super class 的方法中执行 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;
}
我的问题是: 有没有办法在调用第二个 superclass 之前无需手动检查 nullptr 来检查这种恶作剧?
你知道吗,有没有一种优雅的方法可以做到这一点(也许在第二个超级class中)可以让我确信我已经抓住了这种行为的所有可能的例子?
编辑:是的,我知道从 nullptr 调用成员函数不是现代做法。我认为(直到我发布这个问题)它曾经是公认的做法,无论如何我都受到我无法控制的标准的约束。所以,假设在 nullptr 上调用成员函数总是会输入正确的函数,我的问题有没有优雅的解决方案?
foo
是空指针时,foo->getIntValue()
是未定义的,这使得你的整个程序都未定义。
也就是说,取消引用本身是未定义的,你的程序在到达检查之前就注定要失败。
检查 this
是否为空是没有意义的,因为编译器可以自由地假设它不是(如果是,程序将是未定义的,所以编译器可以做任何它想要)。