这是一个相当笼统的问题,但长话短说,我试图找出一种在不使用返回的情况下突破函数的方法。我有一个从模板构建的函数,所以我的编译器不喜欢我使用" return;"如我之前所见,建议尽早终止。以下是我尝试做的简要版本:
V & find (K key) {
TreeNode<K,V> *traverseFind;
//TreeNode<K,V> * treeNode = new TreeNode<K,V> (key,NULL);
traverseFind = root;
unsigned int compareTraverseToHeight = 0;
//A bunch of stuff happens
if(keyFinder == 0) //this is what I have tried to do
return;
return traverseFind->value; //This is what I'm working with, the value can be NULL
}
一些背景:这是二叉树中的查找函数,它包含两个参数key和value。搜索密钥,然后返回其对应的值。作为项目的一部分,我的任务是抛出一个异常,如果输入了一个不在树中的密钥,它会被测试者函数捕获。这样可以正常工作,但是,测试程序的配置方式会在解析之后重新回到函数中,在这种情况下我有traverseFind-&gt; value = NULL,当我尝试返回它时会崩溃我的程序。我无法控制测试人员,所以在我必须返回一个值之前,我想要退出find函数。
这大部分都是好奇的背景。我真正的问题是:而不是我试图使用的if(keyFinder == 0)函数(它没有编译),是否有另一个选项可以用来提前结束函数? A&#34;休息&#34;功能声明可以这么说吗?
更多代码:
#ifndef __CSC116__BST_H__
#define __CSC116__BST_H__
//
// An implementation of a binary search tree.
//
// This tree stores both keys and values associated with those keys.
//
// More information about binary search trees can be found here:
//
// http://en.wikipedia.org/wiki/Binary_search_tree
//
// Note: Wikipedia is using a different definition of
// depth and height than we are using. Be sure
// to read the comments in this file for the
// height function.
//
#include <list>
#include <iostream>
#include <utility>
#include <algorithm>
#include <string>
using namespace std;
unsigned int heightCount = 0;
unsigned int sizeCount = 0;
int keyFinder = 0;
//
// Each node in the tree stores
// both a key and a value
//
template <class K, class V> class TreeNode
{
public:
TreeNode(K k, V v): key(k), value(v), left(0), right(0) {}
K key;
V value;
TreeNode<K,V> *left;
TreeNode<K,V> *right;
template <class X, class Y> friend std::ostream & operator<< (std::ostream &s, const TreeNode<X,Y> &t);
};
//
// TreeNodes can output themselves to streams
template <class K, class V> std::ostream & operator << (std::ostream &s, const TreeNode<K,V> &n)
{
s << "\"" << n.key << ":" << n.value << "\"";
return s;
}
//
// This exception is thrown if you try to find
// a key in the tree that isn't present.
//
class key_not_found_exception {
};
template <class K, class V> class BinarySearchTree {
public:
//
// Constructor
//
BinarySearchTree ()
{
sizeCount = 0;
heightCount = 0;
root = NULL;
}
~BinarySearchTree()
{
}
void insert (K k, V v) {
TreeNode<K,V> * treeNode = new TreeNode<K,V> (k,v);
TreeNode<K,V> *temp=NULL;
TreeNode<K,V> *prev=NULL;
temp = root;
while(temp) {
prev = temp;
if (temp->key < treeNode->key)
temp = temp->right;
else
temp = temp->left;
}
if (prev==NULL)
{root = treeNode;heightCount++;}
else {
if (prev->key<treeNode->key)
{
prev->right = treeNode;
if(prev->left ==NULL){heightCount++;}
}
else
{
prev->left = treeNode;
if(prev->right ==NULL){heightCount++;}
}
}
sizeCount++;
cout << "Height of Tree is:"<<"_" <<heightCount<<endl;
}
V & find (K key)
{
TreeNode<K,V> *traverseFind;
//TreeNode<K,V> * treeNode = new TreeNode<K,V> (key,NULL);
traverseFind = root;
unsigned int compareTraverseToHeight = 0;
while (compareTraverseToHeight < heightCount)
{
if (traverseFind == NULL) // We've fallen off the tree without finding item.
{
keyFinder = 0;
cout<<"code1"<<endl;
cout<<"keyFinder = 0"<<endl;
break;
}
else if ( key == traverseFind->key )// We've found the item.
{
keyFinder = 1;
cout<<"code2"<<endl;
cout<<"keyFinder = 1"<<endl;
break;
}
else if ( key < traverseFind->key ) // If the item occurs, it must be in the left subtree,
{ // So, advance the runner down one level to the left.
traverseFind = traverseFind->left;
cout<<"code3";
}
else // If the item occurs, it must be in the right subtree. // So, advance the runner down one level to the right.
{
traverseFind = traverseFind->right;
cout<<"code4";
}
compareTraverseToHeight++;
} // end while
cout<<"At end of loop, keyFinder ="<<keyFinder<<endl;
try
{
if(keyFinder ==0)
{
cout<<"Try has found that keyFinder = 0"<<endl;
throw key_not_found_exception();
}
else{cout<<"keyFinder = 1"<<endl;}
}catch(...){}
cout<<"RETURNED";
cout<<traverseFind->value<<endl;
if(keyFinder == 0)
{
}
return traverseFind->value;
}
private:
unsigned int doHeight (TreeNode<K,V> *t)
{
return -1;
}
void doDelete (TreeNode<K,V> * n )
{
}
TreeNode<K,V> *root;
unsigned int count;
unsigned int sizeCount;
#endif
TESTER FUNCTION
void test_insert_find()
{
BinarySearchTree<string,string> t;
t.insert("bob", "bobdata");
t.insert("joe", "joedata");
t.insert("jane", "janedata");
try
{
cout<<"Looking for Bob"<<endl;
string s = t.find("bob");
if (s != "bobdata")
throw bst_tester_exception(__func__,__LINE__);
}
catch (key_not_found_exception &e)
{
throw bst_tester_exception(__func__,__LINE__);
}
try
{
cout<<"Looking for Sarah"<<endl;
string s = t.find("sarah");
throw bst_tester_exception(__func__,__LINE__);
}
catch (key_not_found_exception &e)
{
cout<<"Successfully caught"<<endl;
// this is expected.
}
测试的全部输出:
Looking for Bob
code2
keyFinder = 1
At end of loop, keyFinder = 1
keyFinder = 1
RETURNEDbobdata
Looking for Sarah
code4code4code1
keyFinder = 0
At end of loop, keyFinder = 0
Try has found that keyFinder = 0, throwing exception
RETURNED /*Program now crashes when it attempts to return NULL*/
答案 0 :(得分:2)
通常,要从查找类型函数返回“失败”,有两个主要选择:
返回找到的元素(或引用),否则抛出异常。
将指针返回给元素(如果找到),或nullptr
(如果没有)。
还有其他方法,例如返回表示成功的bool
并返回在附加引用或指针参数中找到的元素。
在您的情况下,返回V &
引用,结束函数而不返回值的唯一合理选项是throw
异常。