std :: enable_shared_from_this <> ve çoklu miras [yineleme]

Oct 05 2020

Bu kodu çalıştırmayı denediğimde bad_weak_ptr istisnası alıyorum:

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

C sınıfının bir örneğini oluşturmak ama sonra B shared_ptr döndürmek istiyorum çünkü diğer arayüzün gerektirdiği şey budur. Bu kodu düzeltmenin bir yolu var mı? Bunu yapacak gibi görünmüyorum.

Yanıtlar

Superlokkus Oct 05 2020 at 15:28

Geri alınamaz olanı yapmaya çalıştığını bildiğim kadarıyla:

C ++ 'daki kalıtım, üst sınıfların aynı üyelerini de dahil ettiğiniz anlamına gelir. Ancak bunun için class C, zaten a tarafından tutulması gereken 2 sınıf anlamına gelir std::shared_ptr. Ancak kalıtım yoluyla derleyiciye, C'nin a'nın alt örneklerini içermesi gerektiğini Ave Btarafından tutulmaması gerektiğini söylersiniz std::shared_ptr. shared_from_thiskötü zayıf bir ptr istisnası nedeniyle çalışma zamanında bu durumdan şikayet edecektir.

Muhtemelen C'nin yalnızca a tarafından tutulmasını istersiniz std::shared_ptr, o zaman ekli koda yapabilirsiniz.

Sadece ie'nin bir örneğini "yukarı döküm" yapmak Cistiyorsanız, onu Bsizin bir sınıfınız gibi kullanın, basitçe a kullanabilir B&veya std::shared_ptrdışarıda std::enables_shared_from_thisveya yalnızca en üst sınıfta kullanabilirsiniz.

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