Jason Turner discusses C++ covariant return types, explaining their use in inheritance hierarchies and their limitations. He explores how they apply to pointers and references but not directly to objects. The video also touches on the challenges of using covariant return types with smart pointers and demonstrates an attempt to create a custom covariant smart pointer.
std::shared_ptr do not inherently support covariant return types because std::shared_ptr<Derived> and std::shared_ptr<Base> are not considered related by inheritance, even though Derived inherits from Base.The specific issue encountered when trying to use covariant return types with std::shared_ptr is that std::shared_ptr<Derived> and std::shared_ptr<Base> are not considered related by inheritance from the compiler's perspective. This means that a std::shared_ptr<Derived> cannot be implicitly converted to a std::shared_ptr<Base> when used as a return type in an overridden function, despite the covariant return type feature being generally available for pointers.
// Base class with a pure virtual function
class Base {
public:
virtual ~Base() = default;
virtual Base* get_child() = 0;
};
// Derived class
class Derived : public Base {
public:
virtual ~Derived() = default;
// Covariant return type: returns a pointer to Derived
virtual Derived* get_child() override {
return this; // Example implementation
}
};
// Example of a function attempting covariant return type with objects (which fails)
// This is not directly a snippet from the video but illustrates the point made
/*
class BaseObj {
public:
virtual BaseObj* get_child_obj() = 0;
};
class DerivedObj : public BaseObj {
public:
// This would cause an "invalid covariant return type" error
// virtual DerivedObj get_child_obj() override {
// return DerivedObj();
// }
};
*/
// Example illustrating the shared_ptr issue
/*
#include <memory>
class BaseSP {
public:
virtual ~BaseSP() = default;
virtual std::shared_ptr<BaseSP> get_child_sp() = 0;
};
class DerivedSP : public BaseSP {
public:
virtual ~DerivedSP() = default;
// This would typically fail to compile as std::shared_ptr<DerivedSP>
// is not covariant with std::shared_ptr<BaseSP>
// virtual std::shared_ptr<DerivedSP> get_child_sp() override {
// return std::make_shared<DerivedSP>();
// }
};
*/