如何访问基类shared_ptr二维数组中的派生类并解决operator[]报错
问题根因
运算符不匹配报错原因
arrayOfC本身是类型为std::shared_ptr<C>[800][600]的二维数组,可直接通过[x][y]完成二维索引。你额外对数组名做了*解引用操作,得到的是第一行的一维数组std::shared_ptr<C>[600],执行(*arrayOfC)[(int)x]后已经拿到了第一行第x个std::shared_ptr<C>实例,后续再调用[(int)y]相当于对std::shared_ptr<C>对象使用[]运算符,自然不存在匹配的重载,触发编译错误。
只能访问基类成员的原因
arrayOfC[(int)x][(int)y]的静态类型是std::shared_ptr<C>,编译器只会识别基类C的成员,要访问派生类P的成员需要完成向下类型转换。你之前dynamic_cast失败大概率是两个原因:
- 没有使用智能指针专用的转型接口,直接对
std::shared_ptr<C>实例使用了针对裸指针的dynamic_cast,语法不匹配 - 基类C没有虚函数(不支持RTTI)、P不是public继承自C,或者访问代码处只有C和P的前向声明、没有引入完整类定义,编译器无法识别继承关系
正确访问方案
前置条件
- 基类C至少包含一个虚函数(推荐定义虚析构函数),且派生类P为public继承C
- 访问代码处必须同时引入C和P的完整类定义,不可仅使用前向声明
代码实现
使用std::dynamic_pointer_cast完成shared_ptr的向下转型:
// 先获取数组中的基类智能指针 std::shared_ptr<C> base_ptr = arrayOfC[(int)x][(int)y]; // 转型为派生类P的智能指针 std::shared_ptr<P> derived_ptr = std::dynamic_pointer_cast<P>(base_ptr); if (derived_ptr) { // 转型成功,可正常访问派生类P的成员 derived_ptr->派生类成员函数(); // 也可以直接绑定引用使用 std::shared_ptr<P>& tmpP = derived_ptr; } else { // 转型失败,当前元素不是P类型实例,做错误处理 }
如果100%确认当前位置的元素一定是P类型,可以使用std::static_pointer_cast<P>(base_ptr)跳过运行时类型检查提升性能,但类型不匹配时会触发未定义行为。
内容的提问来源于stack exchange,提问作者David Benz
相关产品推荐
相关产品推荐

