[英]Template iterators, dereferencing, and typedef in C++
我正在從一個正在處理的程序中得到奇怪的結果,無法弄清錯誤在哪里或為什么得到它。 我正在研究使用模板化迭代器的模板化四叉樹類。 即使我的函數似乎正常工作,它也不會返回找到的值。
這是我的基本Quadtree類:
template <class number_type, class label_type>
class QuadTree {
public:
// CONSTRUCTORS
QuadTree() : size_(0), root_(NULL) {}
// ACCESSORS
unsigned int size() const { return size_; }
typedef DepthIterator<number_type, label_type> iterator;
iterator begin() const {
return root_;
}
iterator end() const { return iterator(NULL); }
// This is the function not returning the expected value
iterator find(number_type x, number_type y, Node<number_type, label_type>* parent = NULL) {
if (parent == NULL) {
// start at the root, if equal return, otherwise call recursively
if (root_->pt.x == x && root_->pt.y == y) { return iterator(root_); }
else {
return find(x, y, root_);
}
}
else {
int quadrant;
// find the quadrant of the point
if (x < parent->pt.x && y < parent->pt.y) {
quadrant = 0;
}
else if (x > parent->pt.x && y < parent->pt.y) {
quadrant = 1;
}
else if (x < parent->pt.x && y > parent->pt.y) {
quadrant = 2;
}
else if (x > parent->pt.x && y > parent->pt.y) {
quadrant = 3;
}
// see if the quadrant is a branch or a leaf
if (parent->children[quadrant] == NULL) {
// child is a leaf and it matches the search
if (x == parent->pt.x && y == parent->pt.y) { return iterator(parent); }
// child is a leaf, but it does not match the search
else { return iterator(NULL); }
}
else {
// child is a branch, check if it's equal and return if it is, if not, continue on
if (x == parent->pt.x && y == parent->pt.y) { return iterator(parent); }
else { find(x, y, parent->children[quadrant]); }
}
}
}
private:
unsigned int size_;
Node<number_type, label_type>* root_;
};
似乎我的find函數在我的四叉樹上找到了正確的節點,因為我可以使用std :: cout打印出父級,然后再將其返回正確的值。 然而
return iterator(parent);
給我一個NULL值或點(9,0),它不在我的四叉樹中。
這是我的DepthIterator類:
template <class number_type, class label_type>
class DepthIterator {
public:
// CONSTRUCTOR / COPY / ASSIGN / DECONSTRUCTOR
DepthIterator() : ptr_(NULL) {}
DepthIterator(Node<number_type, label_type>* n) : ptr_(n) {}
DepthIterator(const DepthIterator& old) : ptr_(old.ptr_) {}
~DepthIterator() {}
// OPERATORS
DepthIterator& operator=(const DepthIterator& old) { ptr_ = old.ptr_; return *this; }
const Point<number_type>& operator*() const { return ptr_->pt; }
bool operator== (const DepthIterator& rgt) { return ptr_ == rgt.ptr_; }
bool operator!= (const DepthIterator& rgt) { return ptr_ != rgt.ptr_; }
// ACCESSORS
label_type getLabel() const { return ptr_->label; }
private:
Node<number_type, label_type>* ptr_;
};
也許我的復制或取消引用位是問題嗎? 我傾向於取消引用,因為我的find函數在使用該操作之前有效,但在使用該操作之后無效。
這是我的Node類:
template <class number_type, class label_type>
class Node {
public:
Node() {}
Node(Point<number_type> p, label_type l) : pt(p), label(l) { parent = NULL; }
Node& operator=(const Node& old) { pt = old.pt; label = old.label; parent = *old; return *this; }
Point<number_type> pt;
label_type label;
Node<number_type, label_type>* children[4];
Node<number_type, label_type>* parent;
};
我的主要功能將包含以下內容:
QuadTree<int, char>::iterator itr = test.find(20,10);
// the point (20,10) does exist in the quadtree
assert (itr != test.end());
assert (itr.getLabel() == 'A');
// both of these tests pass
const Point<int> &pt = *itr;
assert (pt.x == 20);
assert (pt.y == 10);
// both of these tests pass
QuadTree<int,char>::iterator itr = test.find(4,7);
// the point (4,7) does exist in the quadtree
assert (itr != test.end());
// this test fails however ^
assert (itr.getLabel() == 'B');
第一個測試有效,但是第二個無效。 我不確定這是否是因為第一個測試是根節點,而第二個測試不是,或者是因為我在中間取消引用,還是完全出於其他原因。 我對C ++還是有些陌生,並且真的很難實現這一點。 誰能解釋為什么我的查找功能不起作用?
iterator find(number_type x, number_type y, Node<number_type, label_type>* parent = NULL) {
if (parent == NULL) {
// start at the root, if equal return, otherwise call recursively
if (root_->pt.x == x && root_->pt.y == y) { return iterator(root_); }
else {
return find(x, y, root_);
}
}
else {
int quadrant;
// find the quadrant of the point
if (x < parent->pt.x && y < parent->pt.y) {
quadrant = 0;
}
else if (x > parent->pt.x && y < parent->pt.y) {
quadrant = 1;
}
else if (x < parent->pt.x && y > parent->pt.y) {
quadrant = 2;
}
else if (x > parent->pt.x && y > parent->pt.y) {
quadrant = 3;
}
// see if the quadrant is a branch or a leaf
if (parent->children[quadrant] == NULL) {
// child is a leaf and it matches the search
if (x == parent->pt.x && y == parent->pt.y) { return iterator(parent); }
// child is a leaf, but it does not match the search
else { return iterator(NULL); }
}
else {
// child is a branch, check if it's equal and return if it is, if not, continue on
if (x == parent->pt.x && y == parent->pt.y) { return iterator(parent); }
else { find(x, y, parent->children[quadrant]); }
}
}
}
問題是如果x == parent-> pt.x或y == parent-> pt.y會導致不確定的行為,因為象限將不會被定義,因為所有if條件都不能為真。 在這種情況下, parent->children[quadrant] == NULL
行為類似於schrodinger的貓,可能是正確的,也可能是錯誤的。
可能的解決方法是:
if (x <= parent->pt.x && y <= parent->pt.y) {
quadrant = 0;
}
else if (x > parent->pt.x && y <= parent->pt.y) {
quadrant = 1;
}
else if (x <= parent->pt.x && y > parent->pt.y) {
quadrant = 2;
}
else if (x > parent->pt.x && y > parent->pt.y) {
quadrant = 3;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.