0

我不认为自己在 C++ 方面知识渊博,但我很难理解这个概念。所以我有一个类,它包含一些模板数据类型和一个双精度。我希望 m_data 变量是通用的,但现在我只使用无符号整数进行测试。当我使用指向无符号整数的指针调用函数 SetData() 时,我丢失了指针指向的信息。当我超出范围时会发生这种情况,所以我觉得我需要对其进行深度复制......

我尝试了许多不同的构造函数和赋值运算符,但我仍然丢失了信息......我觉得我在这里遗漏了一些关于模板的明显内容。如果有人能指出我为什么会丢失数据的正确方向,我会非常感激的。

一小段代码:

template<typename T>
class PointNode {

 public:

  PointNode(double p){ m_point = p;}
  ~PointNode();

 void SetData(T  * data);
 T * GetData() const;

  private:

   double m_point;
   T *m_data;

 };

template<typename T>
void PointNode::SetData(T * data)
{
  m_data = data;
}

template<typename T>
T * PointNode::GetData()
{
  return m_Data;
}

确定更多信息。这个类被存储在另一个类成员的映射中。这里有一点。

 template<typename T>
class AuMathPointTreeT
{

  public:

  //Member Variables 

  double m_dTolerance;  

  unsigned int m_cPoint;         


  map<VectorKey, PointNode<T> > m_tree; /*map posing as a tree */

  typename map<VectorKey, PointNode<T> >::iterator iter;   /* iterator  */
  pair< typename map<VectorKey, PointNode<T> >::iterator, bool > return_val;

  /* Tree methods */

  //constructor
  AuMathPointTreeT(double tol);

 ...
};

在另一个程序中,我正在使用此类,创建节点并像这样设置模板数据

if (node = pnttree.AddPoint(point) )
{
    unsigned int * data = new unsigned int();
    *data = pntCount;
    node->SetData(data);
    ++pntCount;
}

更新:好的发现了问题的罪魁祸首,并想就如何处理它提出建议。当我将一个节点插入映射类时,会在该过程中调用一些函数,并且我会丢失指向新分配的节点类对象的原始指针。这就是我正在做的事情。

template<typename T>
PointNode<T> * AuMathPointTreeT<T>::
AddPoint(double point)
{
  PointNode<T> * prNode = MakeNode(point);

  m_cPoint++;

  return prNode;
} 

template<typename T>
PointNode<T> *  AuMathPointTreeT<T>::
MakeNode(double point)
{
  PointNode<T> * prNode = new PointNode<T>;

    //set the contents for the node just performs a few calcs on the values

  prNode->SetNode(point, m_dTolerance);


  //Create the key class using the 
  VectorKey key(point, m_dTolerance);

  //Store the key,node as a pair for easy access 
  return_val = m_tree.insert( pair<VectorKey, PointNode<T> >(key, *prNode) );
  if (return_val.second == false)
    prNode = NULL;

  unsigned int * test = new unsigned int;
  *test = 55;
  prNode->SetData(test);  //if call this here its no longer the right pointer 

  return prNode;
}

所以看了这个......我真的还是想返回一个指针并使用它。但也许迭代器被 return_val 持有?我也对各个方面的建议持开放态度。对不起,这个问题一团糟:\

4

3 回答 3

0

我认为这与模板的使用没有任何关系。一旦局部变量超出范围,它在堆栈上的位置可能会被其他数据覆盖。

如果您希望模板类实例比其地址传递给 SetData 的局部变量的寿命更长,您应该考虑在堆而不是堆栈上分配数据。无论哪种方式,我都建议用适当的智能指针替换原始 m_data 指针。例如,在模板类及其客户端代码中使用 shared_ptr<> 应减少数据复制量,同时确保数据保持有效,无论原始数据变量是否在范围内。

于 2013-06-06T18:05:29.940 回答
0

如果你想要一个深拷贝,你必须使用 T 而不是 T*,或者你必须使用 T* 进行动态内存分配(但这有点矫枉过正)并且会带来类似的结果。

如果你真的想要指针节点,那就是当你使用你的节点时。

示例:

int number = 5;
Node<int*> oneNode(&number);  // number will die at end of scope
Node<int> anotherNode(number); //anotherNode can be used without risk
于 2013-06-06T18:04:03.630 回答
0

由于您的构造函数,您的代码将无法编译

PointNode(double p){ m_point = p;}

m_point 是 const,你必须将它写入初始化列表:

PointNode(double p) : m_point(p) {}
于 2013-06-06T18:12:27.967 回答