c++ - 从 Derived** 到 Base*const* 的转换

标签 c++

请在链接 parashift 之前阅读我的问题,我可以谷歌搜索,这种情况略有不同。

这是不允许的

Child **cc;
Base ** bb = cc;

因为你可以做到

*bb = new OtherChild;

但是如果我们有

Child **cc;
const Base *const *const bb = cc;

我不认为所有这些常量对于我的示例都是必需的,但只是为了确定..

我认为应该工作的最低限度是

Base *const *bb = cc;

那你不能这样做

*bb = new OtherChild;

所以应该是安全的。但为什么不允许呢?

最佳答案

你混淆了两种情况:

  • 添加const
  • 上行

虽然形式上(在计算机科学理论中)这两者都处理子类化,但实际情况是 C++ 对它们的规则不同,因为 const TT 保证相同,而 Base*Derived* 的表示通常相差一个偏移量(但在涉及虚拟继承时可能完全不同)。

在 3.9.3 中,标准声明

The cv-qualified or cv-unqualified versions of a type are distinct types; however, they shall have the same representation and alignment requirements

给定:

struct Base {};
struct Derived : Base {};
Derived* pd = nullptr;
Base* pb = pd;

const 确实可以按照您建议的方式添加。

Base const* const* const cpcpcb = &pb;
Base* const* pcpb = &pb; // legal, pointer can't be changed
Base const* * ppcb = &pb; // illegal, one could try to rebind the pointer
                          // to a truly const object, then
                          // use pb to mutate the const object

但是Derived*Base*之间没有is-a关系。存在转换,但 Derived* 变量不一定包含 Base 对象(Derived 中的 Base 子对象)的地址 对象可能有不同的地址)。因此,您提示的那一行以及您认为问题有效的那一行都是非法的:

Base const* const* const cpcpcd = &pd; // error, there's no address of a Base
                                       // to be found in pd
Base* const* pcpd = &pd; // error: again, there's no address of a Base
                         // stored in pd

标准在 4.10 中对此进行了正式描述:

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.

转换的结果是纯右值,它没有地址,您不能创建指向它的指针。

关于c++ - 从 Derived** 到 Base*const* 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18102156/

相关文章:

c++ - 在 C++ 中, `var << ifstream` 与 `ifstream >> var` 相同吗?

c++ - 如何使 FindBoost.cmake 工作?

c++ - 通过类析构函数中重置成员shared_ptrs解决C++11shared_ptr循环引用?

c++ - 在 C++ 中将 webM 文件作为参数传递?

C++继承与抽象函数实现

c++ - 如何将文本文件转换为二进制文件,反之亦然?

java - 对 getClass 的 jni 调用为作业对象返回 null

android - 如何使用 Android Studio + Gradle + NDK 构建外部 C++ 库?

C++ - 嵌套包含 - 避免 'include nested too deeply error'

c++ - << 重载运算符,为什么它不能返回类类型(没有引用)