我有以下课程设计:
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
};
以下是我测试课程是否正常工作的主要内容。
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();
}
问题是在成功编译后最终会出现问题 在t-&gt; print()正常工作后,“双重免费或损坏(快速顶部)错误”。 我意识到错误在于通过首先将p1作为t-&gt; inPlaces的成员而创建的循环依赖,其插入t作为p1的成员。但我需要这两种方式链接。此外,我试图通过t-&gt; print()之后的方法重置类Place中的nextTrans的每个成员,但由于指针在一个集合中,因此无效。 那么有人可以建议任何方法来解决这个问题吗?
答案 0 :(得分:6)
这是因为你无法像this
一样制作共享指针。通过这样做,您现在有两个共享指向Trans
实例的指针,它们都指向同一个实例,但它们带有单独的引用计数器。这意味着两者都会尝试delete
指针。
您需要使用std::enable_shared_from_this
。链接的参考页面有一个非常好的问题示例。
答案 1 :(得分:4)
Trans::insertInPlace()
中的这一行:
p->insertNextTrans(shared_ptr<Trans>(this));
创建一个单独的,不相关的共享指针,指向同一个对象。您需要将std::enable_shared_from_this
用于Trans
类:
class Trans: public std::enable_shared_from_this {
// ....
};
然后在Trans::insertInPlace()
:
p->insertNextTrans(shared_from_this());