派生类中调用shared_from_this()返回类型的疑问
先澄清你的误解:shared_from_this()返回的是shared_ptr<A>,但因为C++的多态机制,调用虚函数时会根据对象的实际类型执行B的实现,并不是说返回的是shared_ptr<B>。
具体原因拆解:
shared_from_this()的返回类型由继承的模板参数决定
你的A类继承的是enable_shared_from_this<A>,所以shared_from_this()的签名是shared_ptr<A> shared_from_this(),返回的必然是指向A类型的智能指针。你可以把代码里的auto换成shared_ptr<A>,运行结果完全一致:void func() { cout << "A::func" << endl; shared_ptr<A> ptr = shared_from_this(); ptr->dosomething(); // 依然会调用B::dosomething }多态机制决定了虚函数的调用目标
dosomething()是虚函数,C++的虚函数调用基于对象的实际类型,而非指针/引用的静态类型。这里ptr虽然是shared_ptr<A>,但它指向的对象是B类型(你用make_shared<B>()创建的是B对象),所以调用ptr->dosomething()时,会动态绑定到B::dosomething。enable_shared_from_this的工作逻辑
当你用shared_ptr<B>管理B对象时,这个智能指针会自动初始化A基类中enable_shared_from_this<A>的内部弱引用,这个弱引用指向的是完整的B对象(不是A子对象)。调用shared_from_this()时,会把弱引用升级为shared_ptr<A>,但该指针依然指向B对象的内存地址,所以虚函数调用能正确路由到B的实现。
如果想直接获取shared_ptr<B>?
如果需要在A的成员函数里拿到指向B的智能指针,可以用static_pointer_cast转换:
void func() { cout << "A::func" << endl; auto ptr = static_pointer_cast<B>(shared_from_this()); ptr->dosomething(); // 同样调用B::dosomething }
或者让B也继承enable_shared_from_this<B>(不过这种方式需要注意避免多重继承enable_shared_from_this的潜在问题,更推荐用类型转换的方式)。
内容的提问来源于stack exchange,提问作者Benzecat

