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

C语言面向对象继承实现别名问题:强转子类为父类指针取值错误

问题根源

你对C标准6.7.2.1.13条款的适用场景理解有误,该条款的生效前提是:结构体的首成员是父类的实例,而非父类的指针。
你当前定义的struct Rectangle首成员是Shape*类型的指针,存储的是Shape实例的内存地址,你将Rectangle*强转为Shape*后,Shape_getX/Shape_getY会把Rectangle首地址处存储的指针值当做Shape的x/y成员读取,自然得到错误结果。

修复方案

根据你要隐藏结构体实现的需求,有两种成熟的实现方案可选:

方案1:调整结构体布局,支持直接强转

将Rectangle的首成员改为Shape类型的实例(而非指针),即可符合C标准的规则,强转后读取的值完全正确:

// rectangle.c 中修改结构体定义
struct Rectangle
{
    Shape super; // 改为Shape实例,不是指针
    unsigned int width;
    unsigned int height;
};

// 构造函数对应修改
Rectangle* Rectangle_ctor(int x, int y, unsigned int width, unsigned int height)
{
    Rectangle* me = malloc(sizeof(struct Rectangle));
    // 直接初始化首成员的Shape实例,无需单独malloc
    me->super.x = x;
    me->super.y = y;
    me->width = width;
    me->height = height;

    printf("x: %d\n", Shape_getX(&me->super)); // 正确
    printf("y: %d\n", Shape_getY(&me->super)); // 正确

    printf("x: %d\n", Shape_getX((Shape*)me)); // 现在取值正确
    printf("y: %d\n", Shape_getY((Shape*)me)); // 现在取值正确

    return me;
}

注意:该方案需要将struct Shape的定义放到公共头文件shape.h中,否则Rectangle.c编译时无法获取Shape的内存布局。

方案2:保留指针实现,提供显式转换函数

如果你希望完全隐藏Shape和Rectangle的结构体实现,不需要依赖强转,只需对外提供显式转换函数即可:

  1. 在rectangle.h中新增转换函数声明:
// 新增到rectangle.h
Shape* Rectangle_asShape(Rectangle* me);
  1. 在rectangle.c中实现转换函数:
Shape* Rectangle_asShape(Rectangle* me) {
    return me ? me->super : NULL;
}
  1. 客户端直接调用转换函数即可,无需感知内部实现:
// main.c 中用法
int main(void) {
  Rectangle* r1 = Rectangle_ctor(0, 2, 10, 15);
  printf("r1: (x=%d, y=%d, width=%d, height=%d)\n", Shape_getX(Rectangle_asShape(r1))
                                                  , Shape_getY(Rectangle_asShape(r1))
                                                  , Rectangle_getWidth(r1)
                                                  , Rectangle_getHeight(r1));
  return 0;
}

该方案完全隔离了实现细节,后续就算调整结构体内部布局,只要同步修改转换函数的实现,客户端代码无需任何改动,兼容性更强。

内容的提问来源于stack exchange,提问作者Mr.nerd3345678

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:27:05