std :: enable_shared_from_this <> et héritage multiple [duplicate]

Oct 05 2020

Lorsque j'essaye d'exécuter ce code, j'obtiens une exception bad_weak_ptr:

using namespace std; 

class O {
    public:
        O() {}
};
  
class A : public std::enable_shared_from_this<A>, virtual public O {
    public: 
        A() {}
};

class B : public std::enable_shared_from_this<B>, virtual public O {
    public: 
        B() {}
        void GetShared() { 
            shared_from_this();
        }   
};

class C : public A, public B {
public:
    C()  {}
};
  
int main() 
{ 
    std::shared_ptr<B> pt = std::make_shared<C>();
    pt->GetShared();
}

Je voudrais créer une instance de la classe C mais ensuite retourner B shared_ptr car c'est ce que nécessite une autre interface. Existe-t-il un moyen de corriger ce code? Je n'arrive pas à faire ça.

Réponses

Superlokkus Oct 05 2020 at 15:28

Eh bien, pour autant que je sache, vous essayez de faire l'annulation:

L'héritage en C ++ signifie que vous incluez également les mêmes membres des classes parentes. Cependant pour class Ccela signifierait 2 classes qui sont déjà censées être tenues par un std::shared_ptr. Mais par l'héritage, vous indiquez au compilateur que C doit contenir des sous-instances de Aet Bnon détenues par a std::shared_ptr. shared_from_thisse plaindra de ce fait au moment de l'exécution par une mauvaise exception ptr faible.

Vous voulez probablement que C ne soit détenu que par a std::shared_ptr, alors vous pouvez accéder au code joint.

Si vous voulez simplement "up-cast" une instance de Cie, utilisez-la comme ce serait une classe de Bvous pouvez simplement utiliser a B&ou utiliser std::shared_ptravec out std::enables_shared_from_thisou uniquement sur la classe la plus élevée.

#include <memory>

using namespace std;

class O {
public:
    O() {}
};

struct A : virtual public O {
};

struct B : virtual O {
    B() {}
    void GetShared() {
    }
};

struct C : std::enable_shared_from_this<C>, A, B {
    C() = default;
};

int main()
{
    std::shared_ptr<B> pt = std::make_shared<C>();
    pt->GetShared();
}