我具有以下用于存储子午线和平行线的数据结构。
每个制图点存储:
A]地理和空间坐标,制图失真等
B]指向北/南/东/西节点的指针。
它允许存储点之间的关系,首先将它们与
经络/平行...
class Node2DCart
{
protected:
//Coordinates of the point
double lat;
double lon;
double lattrans;
double lontrans;
double x;
double y;
.....
//Pointers to adjacent points in geographic network
Node2DCart *left;
Node2DCart *right;
Node2DCart *top;
Node2DCart *bottom;
.....
};
子午线的数据结构存储子午线的经度,开始
经络的点和终点以及点数。
class Meridian
{
private:
unsigned int points_count;
double longitude;
Node2DCart *start;
Node2DCart *end;
....
};
所有点都存储在节点列表中:
typedef std::vector<Node2DCart*> TNodes2DCartList;
class Node2DCartList
{
protected:
TNodes2DCartList nodes;
...
};
但是为Node2DList编写副本构造函数存在很大的问题。 Meridian / Parallel与Node2Dlist之间存在循环依赖关系。
复制构造函数使用
std::map
并用新的替换旧的点和链接,这不是一个实现问题...但是,指针从类Meridian点开始/结束,指向旧Node2DList的点... Node2DList复制构造函数应通知所有指向的子午线旧的Node2DList点并将所有指针更改为新的Node2DList点。该模型不允许这样做。可能的解决方案是添加两个指向子午线和平行点所属的指针:
class Node2DCart
{
protected:
//Coordinates of the point
double lat;
double lon;
double lattrans;
double lontrans;
double x;
double y;
.....
//Pointers to adjacent points in geographic network
Node2DCart *left;
Node2DCart *right;
Node2DCart *top;
Node2DCart *bottom;
.....
Meridian *m;
Parallel *p;
};
恐怕这种提议的模型不好。两节课之间仍然有自行车引用资料……有人会帮助我改善它吗?谢谢...
最佳答案
在这种情况下,我通常会采取以下措施:
typedef int node_id_t;
enum { NODE_NULL = 0 };
// or enum node_id_t { NODE_NULL=0 }; for strict typing.
class Node2DCart
{
protected:
node_id_t id; // id of the node
//Coordinates of the point
double lat;
double lon;
double lattrans;
double lontrans;
double x;
double y;
.....
//Pointers to adjacent points in geographic network
node_id_t left;
node_id_t right;
node_id_t top;
node_id_t bottom;
.....
};
class Meridian
{
private:
unsigned int points_count;
double longitude;
node_id_t start;
node_id_t end;
....
};
/* ... */
std::vector<Node2DCart *> node_registry;
// during initialization:
node_registry.push_back( NULL );
// to reserve 0th element to denote the NULL pointer
Node2DCart *
GetNode(node_id_t id)
{
// placeholder of the id range check
return node_registry[id];
};
node_id_t
AddNode(Node2DCart *n)
{
node_registry.push_back(n);
return node_id_t(node_registry.size()-1);
};
然后使用数字
node_id_t
代替Node2DCart *
。还可以抛出std::set
(或std::map
,在AddNode()
中更新/测试),以确保所有Node2DCart对象都是唯一的,并且如果不重用现有对象的ID。本质上是一种寻址方案,为每个节点提供唯一的全局标识符。全局容器不是最好/最简单的解决方案,但对我的帮助不止一次。特别是为了避免内存泄漏并确保彻底破坏相互依赖对象的整个层次结构。
除了
typedef int node_id_t
,还可以使用struct node_id_t { int id; };
和重载转换运算符来简化节点ID查找。