c++类成员访问只看静态类型

cpp 复制代码
struct Base { int b; };
struct Derived : Base { int d; };

Derived dv;
Base* pb = &dv;
Derived* pd = static_cast<Derived*>(pb);

pb 不能访问变量 d ,pb->b 可以,访问 b 可以

cpp 复制代码
pb->b = 1;   // OK,改的就是 dv.b
pb->d = 2;   // 编译错误:'struct Base' has no member named 'd'

原因很简单:成员访问只看静态类型 。pb 的静态类型是 Base*,编译器只认 Base 里声明的成员,而 Base 只有 b。运行时的实际类型是 Derived 这一点,对普通数据成员访问没有任何影响。

几点补充

  1. pb->b 和 dv.b 访问的是同一块内存(Base 子对象),互相可见:

    cpp 复制代码
    pb->b = 1;
    assert(dv.b == 1);
  2. 想通过 pb 访问 d,必须先做转换 ,把静态类型改回 Derived*:

    cpp 复制代码
    static_cast<Derived*>(pb)->d = 2;  // 前提:pb 确实指向 Derived 对象
  3. 虚函数是唯一的"例外" :如果 Base 有虚函数,pb->f() 会按对象的动态类型分派到 Derived::f()。但数据成员没有虚机制,不存在"虚成员变量",所以 pb->d 永远不会合法。

  4. 换成 Base b; Base* p = &b; 也一样 :p->b 合法,p->d 编译不过。区别只在于,此时即使强转成 Derived* 再访问 d 也是 UB ,因为对象本身不是 Derived。

相关推荐
dtq04241 小时前
C++3 - 分支语句if和string变量
开发语言·c++·学习
156082072191 小时前
银河麒麟 Qt 可执行文件打包说明
开发语言·驱动开发·qt
SEO_juper1 小时前
手写 llms.txt 验证器:让 AI 更愿意引用你的网站(GEO)
开发语言·人工智能·python·聚类·seo·独立站
CCCCCCCCharlie1 小时前
从0到1:一个字节的磁盘之旅
linux·开发语言·c++
比兔代理1 小时前
纯净IP是什么?从IP信誉、黑名单与ASN角度原理解析
开发语言·php
benjiangliu1 小时前
恩培趣味计算机视觉-01-conda环境和Python库
开发语言·python·conda
艾莉丝努力练剑1 小时前
【AI大模型接入SDK】ChatServer接口实现
c++·人工智能·学习·ai·架构·大模型·sdk
我喜欢就喜欢2 小时前
DeepSeek Harness 开源贡献手记:从零到合入主线
开发语言·人工智能
要练八块腹肌2 小时前
AVL树的讲解与实现
c++