【问题标题】:upcast at runtime. (Morph from Base Class to derive Class)在运行时向上转换。 (从基类变形为派生类)
【发布时间】:2026-02-04 10:50:01
【问题描述】:
class B{
  private:
    int a;
}
class D: public B{
  private:
    int b;
}

B* b = new B;

现在出于某种原因,我希望 b 变为 D* 类型的对象。 例如保留 B 的信息并成为 D 需要额外的信息。

我目前在想的是。 static_cast 进行向上转换。附加属性将设置为 null 或垃圾。然后手动分配附加属性。但这会导致悬空指针风险。如果对复制构造函数的编码不够谨慎。

那么还有什么合适的解决方案?
如果我们从 PHP 的角度来思考这个难题,还有什么解决方案吗?

【问题讨论】:

  • 为什么要这样做?可能有比通过强制转换将非D 转换为D 更好的解决方案。

标签: php c++ polymorphism casting


【解决方案1】:

如果您执行static_cast<>,那么附加属性将为空或垃圾,它们实际上将在为对象分配的内存之外。使用dynamic_cast<>,如果变量不包含正确的类型,它将正确地失败。

此外,在这种情况下,C++ 和 PHP 之间的相似之处只是表面的;不要使用它来获得对 C++ 代码的进一步“洞察”。

【讨论】:

  • 对不起,我不明白你所说的内爆是什么意思。 dynamic_cast<> 会将其他属性设为 null 或垃圾吗?例如为它分配内存?
  • 是的,我知道,但我必须使架构既可以在 C++ 上作为 CGI 运行,也可以在 PHP 上运行
  • 如果在指向不适当类型的指针上使用,dynamic_cast<> 将返回 NULL。如果您只创建了一个新的B,则没有理智的方法可以为D 提供空间。要么首先创建一个新的D,要么使用现有的B
  • 那么这种铸造方式是没有解决办法的。那么我应该制作一个template<typename From, typename To>class Adapter 模板吗?或类似的东西?调用To 给定From 的某些方法来适应?还是有一个成熟的习语?
  • 耸耸肩 没有人说这很容易。或愉快。如果您需要的是动态语言,那么您应该使用动态语言。
【解决方案2】:

将基础对象重构为派生对象通常是不可能的。首先,分配只为 B 而不是 D 分配了足够的空间。如果您为 D 分配了足够的空间来创建 B 对象(您目前没有,而且无论如何都很难做到),那么您可以使用 hack 来“重建”这样的对象:

// EXTREME HACK, BE CAREFUL, AND USE WITH CARE
// IF YOU DON'T UNDERSTAND IT, DON'T USE IT.
// you should have allocated (sizeof (D)) space to your b pointer.
D* d_object = new (b) D(B(*b));
// you should consider any previous pointer pointing toward the old B* as dangling.

【讨论】:

  • 虽然这可能行得通,但只做D *d = new D(*b); 会更容易、更清晰、更不容易出错。
  • 您需要在D 上有一个复制构造函数,它采用B
  • 我认为为了完整起见它必须存在。可能对从谷歌那里结束的其他人有用
【解决方案3】:

b 指向 B 类型的对象。它不能成为 D。如果你想要一个 D,你必须分配一个并从 *b 复制字段。

永远不要从 PHP 的角度来思考问题,除非你正在用 PHP 编写东西。永远不要用 PHP 写任何东西。

【讨论】:

  • 它与 C++ 模型的有线连接对 PHP 造成了损害。但问题是,如果它有 C++ 的解决方案,那么只有这样它才有任何其他语言的解决方案。如果它在 C++ 中没有解决方案,那么它在其他任何东西中都没有解决方案。
  • 确实有 C++ 中的解决方案。它只是没有您给出的幼稚解决方案。