按值传递共享指针并接受作为基类参数是如何工作的

how does passing shared pointer by value and accepting as base class argument work?

本文关键字:何工作 工作 参数 基类 指针 共享 按值传递      更新时间:2023-10-16

在这个程序中:http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/chat/chat_server.cpp

class chat_session
  : public chat_participant,

chat_session继承chat_participant

shared_ptrchat_session的一次调用中,

被发送给join方法
room_.join(shared_from_this());

定义为

  void join(chat_participant_ptr participant)

那么上面的例子如何转化为particpant是继承类实例的基类指针?

我对基类指针指向继承类实例的理解是来自虚成员这里的例子

http://www.cplusplus.com/doc/tutorial/polymorphism/

——编辑——

如果有人能解释一下,即使我们不使用shared_ptrs

,如何在函数参数中定义指向基类的指针,那就太好了

智能指针在这方面应该像普通的原始指针。使用原始指针,您可以拥有如下所示的函数foo():

void foo(B* pBase);

并且给定一个从B派生的类D,传递一个类型为D*的指针给它:

class D : public B { ... };
// ...
D obj;
foo(&obj); // OK!

这就是派生到基的转换是如何工作的,也是多态性的基础。现在,智能指针旨在模仿这种机制,因此给定:

void foo(shared_ptr<B> pBase);

你可以这样做:

shared_ptr<D> pObj = make_shared<D>();
foo(pObj); // OK!
从技术上讲,shared_ptr类模板实现这种行为的方式是有一个用户定义的构造函数模板来执行隐式转换:
template<class T> class shared_ptr {
public:
    // ...
    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
    // ...
};

只有当Y可转换为T时,这个转换构造函数才会真正参与重载解析。§20.7.2.2.1/17的c++ 11标准规定:

要求:除非Y*是隐式的,否则第二个构造函数不参与重载解析可转换为T* .

这通常通过在函数模板上使用SFINAE约束来实现。

当且仅当

存在从shared_ptr<T>shared_ptr<U>的隐式转换(通过非显式构造函数)
  • Uvoid
  • UT的可访问基类