c++ - 为什么隐式转换不会发生在类型转换的 nullptr 上

标签 c++ multiple-inheritance static-assert

当我遇到一些意想不到的事情时,我试图找到一种方法来静态断言派生类指针可以安全地重新解释为指向基类的指针:

我原以为以下代码中的两个静态断言会失败。

class Base1 {
    int x;
};
class Base2 {
    int y;
};
class Derived : public Base1, public Base2 {
    int z;
};

// one of these should fail???
static_assert( (Derived *)nullptr == (Base1 *)nullptr, "err1" );
static_assert( (Derived *)nullptr == (Base2 *)nullptr, "err2" );
// and one of these as well???
static_assert( (Base1 *)(Derived *)nullptr == nullptr, "err3" );
static_assert( (Base2 *)(Derived *)nullptr == nullptr, "err3" );

对于第一对断言,因为它的参数是 Derived*Base1*/Base2* 类型,我本以为Derived* 隐式转换为 Base1*Base2* 以进行比较。由于 Base1Base2 不能占用相同的内存,因此它们不能都位于 Derived 对象占用的内存的开头,因此其中一个转换应该增加了指针值。那么不应该发现非零指针等于 null。

同样,对于第二对,我希望显式转换为 Base1*Base2* 应该改变其中一个指针,但它们仍然比较等于空。

这是怎么回事?

最佳答案

空指针始终是空指针,并且一直是空指针。

[conv.ptr] (emphasis mine)

3 A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class of D. If B is an inaccessible or ambiguous base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.

由于将 Derived*Base* 进行比较需要将它们转换为通用类型,因此这就是将要发生的转换。如您所见,它保留了空值。

这样做的理由是,不可能从一个空指针值产生一个有效的外观值。如果你从一个空指针值开始,你会坚持下去。

关于c++ - 为什么隐式转换不会发生在类型转换的 nullptr 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58775155/

相关文章:

c++ - 在按下 QPushbutton 时做一些事情

Python调用父方法多重继承

java - 在 Java 中扩展多个类的替换

c - 针对无操作 C 宏的 "semicolon in global scope"警告的解决方法

c++ - 没有 lpthread 的 Promise 中出现未知异常的原因

c++ - AltiVec vec_msum 等效于浮点值

c++ - 如何在 C++ 中使用 smo 库

C++如何从具有不同返回类型的接口(interface)进行多重继承?

c++ - 用于检测模板特化的模板元函数

c++ - 使模板函数编译失败并显示错误消息