Aha*_*han 1 c++ stl shared-ptr
我有以下课程设计:
struct compare{
template <typename T>
bool operator()(const T& a, const T&b){ return *a < *b;}
};
class Trans;
typedef set<shared_ptr<Trans>, compare > TransPointerSet;
class Place{
// other data members
TransPointerSet nextTrans;
public:
// constructor and other methods including overloaded < operator
void insertNextTrans(shared_ptr<Trans> t){ nextTrans.insert(t); }
void removeNextTrans() { nextTrans.clear(); }
};
typedef set<shared_ptr<Place>, compare > PlacePointerSet;
class Trans{
//other data members
PlacePointerSet inPlaces;
PlacePointerSet outPlaces;
public:
//constructor and others including overloaded < operator
void insertInPlace(shared_ptr<Place> p){
inPlaces.insert(p);
p->insertNextTrans(shared_ptr<Trans>(this)); }
void insertOutPlace(shared_ptr<Place> p){ //body }
void print() cosnt { //body }
};
class Net{
TransPointerSet acts;
//other data members
public:
//constructor and others
};
Run Code Online (Sandbox Code Playgroud)
这是我的主要测试类是否正常工作.
int main()
{
shared_ptr<Place> p1 = make_shared<Place>();
shared_ptr<Place> p2 = make_shared<Place>();
shared_ptr<Trans> t = make_shared<Trans>();
t->insertInPlace(p1);
t->insertOutPlace(p2);
t->print();
}
Run Code Online (Sandbox Code Playgroud)
问题是在成功编译之后,在t-> print()正常工作之后,它会以"双重释放或损坏(快速顶部)错误"结束.我意识到错误在于通过首先将p1作为t-> inPlaces的成员创建的循环依赖,其中t作为p1的成员插入.但我需要这两种方式链接.另外,我尝试在t-> print()之后通过一个方法重置类Place中的nextTrans的每个成员,但这不起作用,因为指针在一个集合中.那么有人可以建议任何方法来解决这个问题吗?
这是因为你无法this
像这样制作共享指针.通过这样做,您现在有两个指向该Trans
实例的共享指针,它们都指向同一个实例,但它们具有单独的引用计数器.这意味着两者都会尝试delete
指针.
你需要使用std::enable_shared_from_this
.链接的参考页面有一个非常好的问题示例.
这一行在Trans::insertInPlace()
:
p->insertNextTrans(shared_ptr<Trans>(this));
Run Code Online (Sandbox Code Playgroud)
创建一个单独的、不相关的共享指针到同一个对象。您需要std::enable_shared_from_this
为Trans
类使用:
class Trans: public std::enable_shared_from_this {
// ....
};
Run Code Online (Sandbox Code Playgroud)
然后在Trans::insertInPlace()
:
p->insertNextTrans(shared_from_this());
Run Code Online (Sandbox Code Playgroud)