std :: enable_shared_from_this <> dan beberapa warisan [duplikat]

Oct 05 2020

Ketika saya mencoba menjalankan kode ini, saya mendapatkan pengecualian 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();
}

Saya ingin membuat instance kelas C tetapi kemudian mengembalikan B shared_ptr karena itulah yang dibutuhkan antarmuka lain. Apakah ada cara untuk memperbaiki kode ini? Sepertinya saya tidak bisa melakukan itu.

Jawaban

Superlokkus Oct 05 2020 at 15:28

Sejauh yang saya tahu Anda mencoba melakukan hal yang tidak dapat dilakukan:

Pewarisan dalam C ++ berarti Anda juga menyertakan anggota kelas induk yang sama. Namun untuk class Citu berarti 2 kelas yang sudah seharusnya diadakan oleh a std::shared_ptr. Tetapi dengan pewarisan Anda memberi tahu kompiler bahwa C harus berisi sub-turunan dari Adan Btidak dipegang oleh a std::shared_ptr. shared_from_thisakan mengeluh tentang fakta ini pada saat dijalankan oleh pengecualian ptr lemah yang buruk.

Mungkin Anda ingin C dipegang hanya oleh a std::shared_ptr, lalu Anda bisa ke kode terlampir.

Jika Anda hanya ingin "melakukan up-cast" sebuah instance dari Cie menggunakannya karena itu akan menjadi kelas BAnda dapat menggunakan a B&atau use std::shared_ptrdengan out std::enables_shared_from_thisatau hanya pada sebagian besar class.

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