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

C++继承问题:基类指针能否访问派生类成员变量?

基类智能指针访问派生类成员的差异解析

问题描述

给定基类Shape与派生类Rectangle,尝试通过基类的std::shared_ptr访问Rectangle的成员变量width,代码如下:

class Shape
{
    public:
      Shape() {};
};

class Rectangle : public Shape // 注:原代码遗漏继承关系,此处补充以符合逻辑
{
public:
   Rectangle(int width) : width(width) {} // 修正原构造函数的赋值逻辑为初始化列表
   int width;
};

// 运行时执行代码
std::shared_ptr<Shape> ptr = std::make_shared<Rectangle>(10);
ptr->width; // 此操作会报错?

实际代码中ptr->width会报错,但如果compute_area()是Rectangle重写的成员函数,调用ptr->compute_area()却不会报错,请问这是为什么?

原因解析

1. 访问成员变量width报错的原因

  • C++是静态类型语言,编译阶段会严格检查指针的声明类型。std::shared_ptr<Shape>类型的ptr,编译器仅认为它指向Shape类对象,而Shape类中并没有width成员,因此编译直接报错,不会进入运行阶段。
  • 即便运行时ptr实际指向的是Rectangle对象,静态类型检查不会考虑运行时的实际对象类型,只依据指针的声明类型做校验。

2. 重写的虚函数可以正常调用的原因

  • 这依赖于C++的多态机制:如果基类Shape中把compute_area()声明为虚函数(比如virtual double compute_area() = 0;),那么所有派生类的对象会携带一个指向虚函数表(vtable)的指针。
  • 当通过基类指针调用虚函数时,程序会在运行时根据实际指向的对象类型(这里是Rectangle),找到对应类的虚函数表,进而调用Rectangle中重写的compute_area()版本。
  • 注意:如果基类没有将compute_area()声明为虚函数,直接调用ptr->compute_area()要么会调用基类的版本(若基类有该函数),要么同样会编译报错(若基类无此函数)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:22:26