georg774
georg774

Reputation: 25

Getting shared pointer from this of derived class in C++

I want to get shared_ptr from this of derived class.
std::enable_shared_ptr_from_this inherited by base class and gets std::shared_ptr<Base>, but not std::shared<Derived>. I can use std::reinterpret_pointer_cast or std::dynamic_pointer_cast but

  1. is so much code
  2. is it safe when multiple inheritance used?
    Or it is the only way?

Example code:

class Base : public std::enable_shared_from_this<Base> {

};

class Derived : public Base {
public:
    std::shared_ptr<Derived> GetPointer() const {
        return shared_from_this(); // but it returns std::shared<Base> type
    }
};

Thanks in advance!

Upvotes: 1

Views: 531

Answers (1)

Tofu
Tofu

Reputation: 3613

It's perfectly fine and safe to do it the way you're currently doing.

#include <memory>

class Base : public std::enable_shared_from_this<Base>{
public:
    virtual int32_t getid() = 0;
};
class Derived : public Base{
public:
    int32_t id;
    Derived(int32_t id){
        this->id = id;
    }
    ~Derived(){
        
    }
    int32_t getid(){
        return id;
    }
};
int main(){
    std::shared_ptr<Derived> child = std::make_shared<Derived>(1033);
    std::shared_ptr<Base> parent = child;//This needs no extra work
    std::shared_ptr<Derived> secondchildinstance = std::static_pointer_cast<Derived>(parent);//this needs casting
    if(secondchildinstance!=nullptr){
        //shared_from_this can be called directly from the child without an explicit method
        std::shared_ptr<Base> secondparentinstance = secondchildinstance->shared_from_this();
        
        //shared_from_this would require downcasting to get the child
        std::shared_ptr<Derived> thirdchildinstance =  std::static_pointer_cast<Derived>(secondchildinstance->shared_from_this());//requires casting
        
        if(thirdchildinstance!=nullptr){
            printf("use count:%ld id:%d",thirdchildinstance.use_count(),thirdchildinstance->getid());
        }
    }
    return 0;
}

You probably could make your job for down-casting from parent to child easier through a wrapper method.

Something to note is, you do not need an explicit method in order to call shared_from_this, because the parent already inherits it you can call the child->shared_from_this() directly but it will give the shared instance of the base class which will need downcasting.

Upvotes: 2

Related Questions