哪种类型的智能指针(共享,作用域)最适合这样的数据结构......
结构1:
//Class with cross-references to points p1, p2
class PointTopo
{
private:
double x, y;
PointTopo * p1;
PointTopo * p2;
public:
PointTopo(double xx, double yy): x(xx), y(yy) {this-> p1 = NULL; this->p2 = NULL;}
...
};
结构2:
//Class with cross references: topological model for Delaunay triangulation
class Edge
{
private:
Point * start; //Only 2D point without topo information
Edge *next;
Edge *previous;
Edge *twin;
...
};
我想使用vector存储Edges和PointTopo:
class PointsTopoList
{
private:
std::vector <PointTopo *> points;
public:
inline void push_back ( PointTopo *p ) { points.push_back ( p );}
~PointsTopoList() {clear();}
void clear()
{
for ( TNodes2DList::iterator i_points= points.begin(); i_points!= points.end(); ++i_points)
{
if ( *i_points!= NULL )
{
delete *i_points;
*i_points= NULL;
}
points.clear();
}
}
但是析构函数存在问题,所以我想知道是否使用引用计数。
int main()
{
PointTopo *p1 = new PointTopo(0,0);
PointTopo *p2 = new PointTopo(10,10);
PointTopo *p3 = new PointTopo(20,20);
PointTopo *p4 = new PointTopo(30,30);
PointsTopoList tl1;
tl1.push_back(p1);
tl1.push_back(p2);
tl1.push_back(p3);
tl1.push_back(p4);
PointsTopoList tl2;
tl2.push_back(p1); //P1 is stored in tl1 and tl2
tl2.push_back(p2); //P2 is stored in tl1 and tl2
}
点p1,p2将存储在列表t1,tl2中。 tl2的析构函数导致异常,使用tl1析构函数删除了点p1和p2。
此示例不是合成的。想象一下,nl2代表nl1的子集,例如nl1的凸包......
我认为,如果没有引用计数,这个问题就无法解决......所以我尝试使用一些智能指针......
非常感谢你的帮助......
答案 0 :(得分:2)
tl2的析构函数导致异常,使用tl1析构函数删除了点p1和p2。
您正尝试delete
对象p1
(和p2
)两次。这会引发UB - 这是一件坏事。尝试在shared_ptr
命名空间中可用的std::tr1
(引用计数智能指针)(有关详细信息,请参阅编译器文档)或Boost。
另一件事是复制对象(而不是现在正在执行的指针)。这需要复制PointTopo
个对象。
(就我个人而言,我倾向于unique_ptr
和Edge
成员单独使用PointTopo
。)
答案 1 :(得分:2)
shared_ptr<>
确实引用了对同一个对象的几个指针的计数和管理,当对象的最后一个指针被销毁时删除该对象。
scoped_ptr<>
使指针的行为类似于堆栈变量,只要指针超出范围,它就会删除指向的对象。这不是你在这里寻找的行为。
在您的用例中,shared_ptr<>
提供的引用计数是您想要的。
答案 2 :(得分:1)
你需要的是一个boost :: shared_ptr