From cppreference,
If
T
is a derived class of some baseB
, thenstd::unique_ptr<T>
is implicitly convertible tostd::unique_ptr<B>
which it obviously must be for polymorphism to work as it does with raw pointers. My question is, if a smart pointer is not generally convertible to a pointer as we can see here, then what is the mechanism used by the smart pointer to allow for runtime polymorphism? My thinking is that either in a constructor or std::make_unique<>()
/std::make_shared<>()
the internal pointer in the object is used for this conversion. But if these implicit conversions aren't allowed anywhere else, why don't we have to call get() when constructing our smart pointers?
As a very simple example I came up with the following test:
#include <iostream>
#include <memory>
class Base
{
public:
virtual ~Base() = default;
virtual void foo() const { std::cout << "Base foo() called." << std::endl; }
};
class Derived : public Base
{
public:
virtual void foo() const override { std::cout << "Derived foo() called." << std::endl; }
};
void bar(Base* pBase)
{
std::cout << "bar() called." << std::endl;
pBase->foo();
}
int main()
{
std::unique_ptr<Base> pObject { std::make_unique<Derived>() }; // Implicit conversion here, why no call to get()?
// bar(pObject); // Can't be converted, so we have to call get()
bar(pObject.get());
}