c++ - 为什么在类型转换的 nullptr 上不会发生隐式转换
问题描述
当我遇到意想不到的事情时,我试图找到一种静态断言派生类指针可以安全地重新解释为指向基类的指针的方法:
我预计以下代码中的两个静态断言会失败。
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*
将隐式转换为 a Base1*
orBase2*
进行比较。由于Base1
和Base2
不能占用相同的内存,它们不能都位于Derived
对象占用的内存的开头,因此这些转换之一应该增加了指针值。然后不应该发现非零指针等于空。
同样,对于第二对,我希望显式转换为Base1*
并且Base2*
应该更改其中一个指针,但它们仍然比较等于 null。
这里发生了什么?
解决方案
空指针始终是空指针,并且它始终是空指针。
[conv.ptr](强调我的)
3 “指向 cv 的指针
D
”类型的纯右值,其中D
是类类型,可以转换为“指向 cv 的指针B
”类型的纯右值,其中B
是 的基类D
。如果B
是 的一个不可访问或模棱两可的基类D
,则需要进行此转换的程序格式错误。转换的结果是指向派生类对象的基类子对象的指针。空指针值转换为目标类型的空指针值。
由于将 aDerived*
与 a进行比较Base*
需要将它们转换为通用类型,因此这就是将要发生的转换。如您所见,它保留了空值。
这样做的基本原理是不可能从空指针值产生一个看起来有效的值。如果您从空指针值开始,您将继续使用它。
推荐阅读
- java - 当我启动 Activity 时,在 onCreate() 之后调用 OnDestroy()
- python - 为什么python dict的id不变?
- python - 如何在 GET 请求之前清理用户提供的 URL?
- m2doc - M2DOC DRepresentation isVisibleInDoc
- java - 比较 csv 文件和 MySQL 数据库
- android - 如何管理活动中创建方法的 4 或 5 个 API 调用?
- javascript - 如何在 App 脚本中循环使用 Google 表格公式
- python - 以日期值为条件计算平均值和差异
- java - 当 A 层/B 层需要相同功能时,如何避免创建重复的微服务
- reactjs - 我想用 React 在 const 中调用一个函数,但 React 没有正确显示函数