You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将联合指针转换为未知活跃成员的已知基类指针是否合法?

联合中通过void*转换为基类指针的合法性问题

已知一个联合的活跃成员均派生自某个非标准布局基类,但不确定具体哪个成员是活跃成员。能否通过void*将联合指针转换为基类指针并使用?比如以下可通过g++ 11.3.0在-std=c++23下编译的代码是否合法?

class base { public: virtual bool foo() = 0; };

class derived_1 : public base { bool foo() override { return true; }; };

class derived_2 : public base { bool foo() override { return false; }; };

union some_base {
  derived_1 x;
  derived_2 y;

  bool foo() {
    return static_cast<base *>(static_cast<void *>(this))->foo();
  };
};

这段代码不符合C++标准规定,属于未定义行为,原因如下:

  • 指针转换的合法性存疑:
    static_cast<void*>(this)得到的是联合对象的起始地址,联合的所有成员都从该地址开始布局,因此该地址等于活跃成员(derived_1或derived_2)对象的起始地址。但static_cast<base*>(void_ptr)的合法前提是,void_ptr必须指向base类型的对象或其派生类对象的base子对象。虽然单继承非虚基类场景下,编译器通常会让派生类对象地址与基类子对象地址重合,但C++标准并未强制保证这一点——非标准布局类型的基类子对象位置由编译器自由决定。即使地址相同,标准也不允许直接将指向派生类对象的void*转换为基类指针,除非该void*是从基类指针转换而来的。

  • 违反联合活跃成员的访问规则:
    根据C标准,联合的非活跃成员不能被访问,仅能合法操作活跃成员的成员。虽然你知道活跃成员是derived_1或derived_2,但通过联合指针转void*再转base*的方式,并未明确指向活跃成员的基类子对象,而是绕开了联合成员的直接访问路径。这种操作未被标准明确允许,属于未定义行为——当前g能运行只是编译器的实现特性,而非标准保证的可移植行为。


正确实现方式

如果需要实现类似需求,正确的做法是在联合中维护一个标记,记录当前活跃成员的类型,再根据标记获取对应成员的指针并转换为基类指针:

#include <stdexcept>

class base { public: virtual bool foo() = 0; };

class derived_1 : public base { bool foo() override { return true; }; };

class derived_2 : public base { bool foo() override { return false; }; };

enum class ActiveMember { Derived1, Derived2 };

union some_base {
  derived_1 x;
  derived_2 y;
  ActiveMember active;

  // 构造函数初始化活跃成员及标记
  some_base() : x(), active(ActiveMember::Derived1) {}
  some_base(decltype(x)) : x(), active(ActiveMember::Derived1) {}
  some_base(decltype(y)) : y(), active(ActiveMember::Derived2) {}

  bool foo() {
    switch(active) {
      case ActiveMember::Derived1:
        return static_cast<base*>(&x)->foo();
      case ActiveMember::Derived2:
        return static_cast<base*>(&y)->foo();
      default:
        throw std::runtime_error("无有效活跃成员");
    }
  };
};

内容的提问来源于stack exchange,提问作者Shea Levy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:50:35