今天在阅读AirSim源代码时,发现其中对同一个对象使用了make_shared,和shared_from_this两种方式来获取同一个对象的shared_ptr.对这种方法,我十分担心是否会出现对象被重复释放的情况,于是进行了以下实验:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class TestClass{}; class shared_TestClass : public TestClass, public enable_shared_from_this<shared_TestClass> {}; { TestClass* ptr = new TestClass(); using TCptr = shared_ptr<TestClass>; TCptr shared_ptr_1(ptr); TCptr shared_ptr_2(ptr); }//重复释放 { shared_TestClass* ptr = new shared_TestClass; using STCptr = shared_ptr<shared_TestClass>; STCptr shared_ptr_1(ptr); STCptr shared_ptr_2(ptr); }//重复释放 { auto ptr = make_shared<shared_TestClass>(); shared_ptr<shared_TestClass> shared_ptr(ptr); }//正确释放 { auto ptr = make_shared<shared_TestClass>(); auto ptr2 = ptr->shared_from_this(); }//正确释放 |
其中:
第一种代码是明显错误的情况.对同一个指针创建了两个不属于同一个ownership group的shared_ptr,这两个shared_ptr会分别对该对象进行销毁,产生错误.
第二种代码中的对象尽管继承了enable_shared_from_this,然而从这个对于shared_ptr而言,并不会自动获取shared_from_this()的值(不知道这里是否可能用模板处理特例呢?),依然产生错误.
第三种代码是shared_ptr的标准用法.
第四种代码是我在AirSim看到的两种获取shared_ptr方式,可见是在同一个ownership group的,即enable_shared_from_this提供了一种不需要其他shared_ptr,就可以从对象本身获得shared_ptr的侵入式的方式.
目前可以想到的使用场景是,在外部和该对象内部保存的callback等不属于本对象的代码,都需要参与该对象的生命周期管理时(如外部保存一个shared_ptr,内部保存着其他地方注册的callback(为了保证生命周期也要传shared_ptr)),就可以采用enable_shared_from_this,来保证ownership group.
你好,,我想问下,你这个blog模板是哪里弄的,我也想弄一个,能给些指导吗
您好,您可以查看这个repo中的Wordpress主题:https://github.com/justliqiang/Sirius