std :: enable_shared_from_this <> และการสืบทอดหลายรายการ [ซ้ำกัน]

Oct 05 2020

เมื่อฉันพยายามเรียกใช้รหัสนี้ฉันได้รับข้อยกเว้น 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();
}

ฉันต้องการสร้างอินสแตนซ์ของคลาส C แต่ส่งกลับ B shared_ptr เพราะนั่นคือสิ่งที่อินเทอร์เฟซอื่นต้องการ มีวิธีแก้ไขโค้ดนี้หรือไม่? ดูเหมือนฉันจะทำอย่างนั้นไม่ได้

คำตอบ

Superlokkus Oct 05 2020 at 15:28

เท่าที่ฉันรู้ว่าคุณกำลังพยายามยกเลิกการทำ:

การสืบทอดใน C ++ หมายความว่าคุณรวมสมาชิกเดียวกันของคลาสพาเรนต์ด้วย อย่างไรก็ตามclass Cนั่นจะหมายถึง 2 คลาสที่ควรจะจัดขึ้นโดย a std::shared_ptr. แต่โดยการสืบทอดคุณบอกคอมไพลเลอร์ว่า C ควรมีอินสแตนซ์ย่อยAและBไม่ถูกยึดโดย a std::shared_ptr. shared_from_thisจะบ่นเกี่ยวกับข้อเท็จจริงนี้ในเวลาดำเนินการโดยข้อยกเว้น ptr ที่อ่อนแอไม่ดี

คุณอาจต้องการให้ C จับด้วย a เท่านั้นจากstd::shared_ptrนั้นคุณสามารถแนบรหัสที่แนบมาได้

หากคุณเพียงต้องการที่จะ "ขึ้นนำแสดงโดย" อินสแตนซ์ของCเช่นใช้เป็นก็จะเป็นชั้นของBคุณก็สามารถใช้B&หรือการใช้งานstd::shared_ptrที่มีออกมาstd::enables_shared_from_thisหรือเฉพาะขึ้นระดับมากที่สุด

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