Bar() : Foo(this) {}
当你this
转到一个时要小心shared_ptr
.
想想以后会发生什么f.resetBar();
,并ptr.reset(new Bar);
再次.
因为new Bar
,Bar
将构造一个类型的对象,并在其构造函数内部this
传递给父类成员ptr
,然后该对象由它来管理std::shared_ptr
.
之后,对象由f.ptr
; 这是另一个std::shared_ptr
.
所以有两个人std::shared_ptr
指向同一个对象,但是std::shared_ptr
对此却一无所知; 因为你是单独构建它们的.当f
和f.ptr
被破坏时,指向的对象也将被破坏.然后该成员ptr
将被销毁,它将再次尝试销毁同一个对象,从而导致UB.
我不确定设计试图完成什么,但只是停止传递this
到一个std::shared_ptr
可以消除UB.
class Foo { public: virtual ~Foo() = default; void whatever() { if (ptr) ptr->whateverHandler(); } void reset() { ptr.reset(); } void resetBar() { ptr.reset(new Bar); } // Other resets here... private: // Every child class should override this virtual void whateverHandler() = 0; std::shared_ptrptr; }; class Bar : public Foo { public: void whateverHandler() { printf("Bar's handler!!! \n"); } }; int main() { { Foo f; f.resetBar(); f.whatever(); f.resetSthElse(); f.whatever(); } }
而IMO,有一个类型的成员std::shared_ptr
指向派生类是令人困惑的; 将它分开可能会更好.然后,我认为这可能是桥梁设计的一部分.
class Foo { public: void whatever() { if (ptr) ptr->whateverHandler(); } void reset() { ptr.reset(); } void resetBar() { ptr.reset(new BarHandler); } // Other resets here... private: std::shared_ptrptr; }; class FooHandler { public: virtual ~FooHandler() = default; // Every child class should override this virtual void whateverHandler() = 0; }; class BarHandler : public FooHandler { public: void whateverHandler() { printf("Bar's handler!!! \n"); } }; int main() { { Foo f; f.resetBar(); f.whatever(); f.resetSthElse(); f.whatever(); } }