std :: enable_shared_from_this <> e ereditarietà multipla [duplicato]

Oct 05 2020

Quando provo a eseguire questo codice ottengo l'eccezione 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();
}

Vorrei creare un'istanza della classe C ma poi restituire B shared_ptr perché questo è ciò che richiede l'altra interfaccia. C'è un modo per correggere questo codice? Non riesco a farlo.

Risposte

Superlokkus Oct 05 2020 at 15:28

Beh, per quanto ne so stai cercando di fare l'annullabile:

L'ereditarietà in C ++ significa che includi anche gli stessi membri delle classi padre. Tuttavia, class Cciò significherebbe 2 classi che dovrebbero già essere tenute da a std::shared_ptr. Ma in base all'ereditarietà si dice al compilatore che C dovrebbe contenere subistanze di Ae Bnon detenute da a std::shared_ptr. shared_from_thissi lamenterà di questo fatto in fase di esecuzione con un'eccezione ptr debole e debole.

Probabilmente vuoi che C sia tenuto solo da a std::shared_ptr, quindi puoi farlo con il codice allegato.

Se vuoi semplicemente "up-cast" un'istanza di Cie usala come se fosse una classe di Bte, puoi semplicemente usare a B&o usare std::shared_ptrsenza std::enables_shared_from_thiso solo sulla classe più alta.

#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();
}