Chinaunix

标题: 我需要一个使用stl库中的异常类的例子,谢谢! [打印本页]

作者: fibbery    时间: 2008-08-11 15:35
标题: 我需要一个使用stl库中的异常类的例子,谢谢!
我想在我写的代码中使用stl库中的异常类作为我的程序中的异常类!

哪位能给一个抛出和捕获的例子,谢谢!
作者: DraculaW    时间: 2008-08-11 15:35

  1. #ifndef _LINKEDLIST_H_
  2. #define _LINKEDLIST_H_

  3. #include <stdexcept>

  4. using namespace std;

  5. class EmptyListException : public logic_error {
  6. public:

  7.     EmptyListException(const string& what_arg ) throw() :

  8.       logic_error ("Empty list exception: " + what_arg) {}
  9. };

  10. template <class T>
  11. class Node {
  12. private:
  13.     T data;
  14.     Node* next;

  15. public:
  16.     Node(T d, Node* n = NULL) : data(d), next(n) {}

  17.     T& getData() { return data;}

  18.     Node*& getNext() { return next;}
  19. };

  20. template <class T>
  21. class LinkedList {
  22. protected:
  23.     Node<T>* head; // Beginning of list

  24.     Node<T>* tail; // End of list

  25.     int count; // Number of nodes in list

  26. public:
  27.     LinkedList(void) : head(NULL), tail(NULL), count(0) {}

  28.     LinkedList(const LinkedList<T>& src); // Copy constructor

  29.     virtual ~LinkedList(void); // Destructor

  30.     virtual T& front(void) {
  31.         if (head == NULL) {
  32.             throw EmptyListException("front()");
  33.         }

  34.         return head->getData();
  35.     }

  36.     virtual T& back(void) {
  37.         if (tail == NULL) {
  38.             throw EmptyListException("back()");
  39.         }
  40.         return tail->getData();
  41.     }

  42.     virtual int size(void) {
  43.         return count;
  44.     }

  45.     virtual bool empty(void) {
  46.         return count == 0;
  47.     }

  48.     virtual void push_front(T); // Insert element at beginning

  49.     virtual void push_back(T); // Insert element at end

  50.     virtual void pop_front(void); // Remove element from beginning

  51.     virtual void pop_back(void); // Remove element from end

  52.     virtual void dump(void); // Output contents of list
  53. };

  54. // Copy constructor
  55. template <class T>
  56. LinkedList<T>::LinkedList(const LinkedList<T>& src) :
  57. count(0), head(NULL), tail(NULL) {
  58.     Node<T>* current = src.head;
  59.     while (current != NULL) {
  60.         this->push_back(current->getData());
  61.         current = current->getNext();
  62.     }
  63. }

  64. // Destructor
  65. template <class T>
  66. LinkedList<T>::~LinkedList(void) {
  67.     while (!this->empty()) {
  68.         this->pop_front();
  69.     }
  70. }

  71. // Insert an element at the beginning
  72. template <class T>
  73. void LinkedList<T>::push_front(T d) {

  74.     Node<T>* new_head = new Node<T>(d, head);

  75.     if (this->empty()) {
  76.         head = tail = new_head;
  77.     }
  78.     else {
  79.         head = new_head;
  80.     }

  81.     count++;
  82. }

  83. // Insert an element at the end
  84. template <class T>
  85. void LinkedList<T>::push_back(T d) {

  86.     Node<T>* new_tail = new Node<T>(d, NULL);

  87.     if (this->empty()) {
  88.         head = new_tail;
  89.     }
  90.     else {
  91.         tail->getNext() = new_tail;
  92.     }

  93.     tail = new_tail;
  94.     count++;
  95. }

  96. // Remove an element from the beginning
  97. template <class T>
  98. void LinkedList<T>::pop_front(void) {

  99.     if (head == NULL) {
  100.         throw EmptyListException("pop_front()");
  101.     }

  102.     Node<T>* old_head = head;

  103.     if (this->size() == 1) {
  104.         head = NULL;
  105.         tail = NULL;
  106.     }
  107.     else {
  108.         head = head->getNext();
  109.     }

  110.     delete old_head;
  111.     count--;
  112. }

  113. // Remove an element from the end
  114. template <class T>
  115. void LinkedList<T>::pop_back(void) {
  116.     if (tail == NULL) {
  117.         throw EmptyListException("pop_back()");
  118.     }

  119.     Node<T>* old_tail = tail;

  120.     if (this->size() == 1) {
  121.         head = NULL;
  122.         tail = NULL;
  123.     }

  124.     else {
  125.         // Traverse the list
  126.         Node<T>* current = head;
  127.         while (current->getNext() != tail) {
  128.             current = current->getNext();
  129.         }

  130.         // Unlink and reposition
  131.         current->getNext() = NULL;
  132.         tail = current;
  133.     }

  134.     delete old_tail;
  135.     count--;
  136. }

  137. // Display the contents of the list
  138. template <class T>
  139. void LinkedList<T>::dump(void) {
  140.     cout << "(";

  141.     if (head != NULL) {
  142.         Node<T>* current = head;
  143.         while (current->getNext() != NULL) {
  144.             cout << current->getData() << ", ";
  145.             current = current->getNext();
  146.         }
  147.         cout << current->getData();
  148.     }

  149.     cout << ")" << endl;
  150. }
  151. #endif



  152. #ifndef _ENHANCELINKLIST_H_
  153. #define _ENHANCELINKLIST_H_

  154. #include "LinkedList.h"

  155. template<typename T>
  156. class EnhancedLinkedList: public LinkedList<T>
  157. {
  158. public:
  159.     T& find_first (const T& key);

  160.     //Method find_first should search the EnhancedLinkedList for the first
  161.     //occurrence of an item that matches the value in the parameter key.
  162.     //It should return a reference to the first matching item.
  163.     //If the invoking EnhancedLinkedList object is empty or no item is found
  164.     //that matches the parameter, a ListItemNotFoundException should be thrown.
  165.     //You will have to define this exception
  166.     //(Hint: define this exception much the same way that the
  167.     //EmptyListException exception is defined in LinkedList.h).

  168.     EnhancedLinkedList find_all (const T& key);
  169.     //Method find_all should search the invoking EnhancedLinkedList
  170.     //for all elements that match the value in the parameter key.
  171.     //It should return an EnhancedLinkedList object containing
  172.     //copies of all the items that match the parameter key.
  173.     //If the invoking EnhancedLinkedList object is empty or
  174.     //no item is found that matches the parameter,
  175.     //this function should return an empty EnhancedLinkedList.

  176.     void remove_first (const T& key);
  177.     //Method remove_first should remove the first element from the
  178.     //invoking EnhancedLinkedList whose data item matches the parameter key.
  179.     //If the invoking EnhancedLinkedList object is empty or no item is found
  180.     //that matches the parameter, this function should do nothing.
  181.     //Remember to leave no memory leaks.

  182.     void remove_all (const T& key);
  183.     //Method remove_all should remove all elements from the invoking
  184.     //EnhancedLinkedList whose data items match the parameter key.
  185.     //If the invoking EnhancedLinkedList object is empty or no item is found
  186.     //that matches the parameter, this function should do nothing.
  187.     //Remember to leave no memory leaks.
  188. };

  189. template<typename T>
  190. T& EnhancedLinkedList<T>::find_first(const T& key)
  191. {
  192.     Node<T>* temp = this->head;

  193.     if(temp == NULL)
  194.         throw EmptyListException("Find first emptylist");

  195.     while(NULL != temp->getNext())
  196.     {
  197.         if(temp->getData()==key)
  198.             return temp->getData();
  199.         else
  200.             temp=temp->getNext();
  201.     }

  202.     throw EmptyListException("Find first not found");
  203. }

  204. template<typename T>
  205. EnhancedLinkedList<T>
  206. EnhancedLinkedList<T>::find_all(const T& key)

  207. {
  208.     EnhancedLinkedList<T> resualt;

  209.     Node<T>* temp = this->head;

  210.     while(NULL != temp)
  211.     {
  212.         if(temp->getData()==key)
  213.             resualt.push_back(temp->getData());
  214.         temp=temp->getNext();
  215.     }

  216. end:
  217.     return resualt;
  218. }

  219. template<typename T>
  220. void
  221. EnhancedLinkedList<T>::remove_first(const T& key)

  222. {
  223.     EnhancedLinkedList<T> list;
  224.     while(NULL!=this->head)
  225.     {
  226.         if(this->head->getData()!=key)
  227.             list.push_front(this->head->getData());
  228.         else{
  229.             T* temp = this->front();
  230.             this->pop_front();
  231.             delete temp;
  232.             break;
  233.         }
  234.         this->pop_front();
  235.     }

  236.     while(list.head!=NULL)
  237.     {
  238.         this->push_front(list.front());
  239.         list.pop_front();
  240.     }
  241. }

  242. template<typename T>

  243. void

  244. EnhancedLinkedList<T>::remove_all(const T& key)
  245. {
  246.     EnhancedLinkedList<T> list;

  247.     while(NULL!=this->head)
  248.     {
  249.         if(this->head->getData()!=key){
  250.             list.push_front(this->head->getData());
  251.             this->pop_front();
  252.         }
  253.         else{
  254.             T* temp = this->front();
  255.             this->pop_front();
  256.             delete temp;
  257.         }
  258.     }

  259.     while(list.head!=NULL)
  260.     {
  261.         this->push_front(list.front());
  262.         list.pop_front();
  263.     }
  264. }
  265. #endif //_ENHANCELINKLIST_H_
复制代码


大学时候的一道作业题 有你想要的东西

[ 本帖最后由 DraculaW 于 2008-8-11 16:55 编辑 ]
作者: tyc611    时间: 2008-08-11 16:00
你想抛出什么异常就直接抛出,跟STL没关系
作者: converse    时间: 2008-08-11 16:02
class Exception
{
...
};

...
throw Exception();

catch (Exception)
{
  ....
}


这跟STL有嘛关系?
作者: fibbery    时间: 2008-08-11 16:10
不知道是不是我的问题!!

我知道甚至可以抛出一个int类型的异常,我想使用stl中的异常,但我不知道对于stl异常来说,在抛出之前我需要做什么,跑出之后我都可以做什么!
作者: tyc611    时间: 2008-08-11 16:25
原帖由 fibbery 于 2008-8-11 16:10 发表
不知道是不是我的问题!!

我知道甚至可以抛出一个int类型的异常,我想使用stl中的异常,但我不知道对于stl异常来说,在抛出之前我需要做什么,跑出之后我都可以做什么!

可以抛出任何类型的异常,使用方法都一样
另外STL指标准模板库,我觉得你想说的是C++标准库,C++标准库 != STL,后者是前者的子集
作者: yulc    时间: 2008-08-11 16:34
原帖由 fibbery 于 2008-8-11 16:10 发表
不知道是不是我的问题!!

我知道甚至可以抛出一个int类型的异常,我想使用stl中的异常,但我不知道对于stl异常来说,在抛出之前我需要做什么,跑出之后我都可以做什么!



你是指STL中的exception 类吧.
如果你想抛出这个类的对象,我记得是你先要声明一个该类的子类,像这样:
class MyException : public exception
{

};

然后你就可以 throw MyException();
作者: fibbery    时间: 2008-08-11 16:35
to tyc661:

我确实不知道C++标准程序库不等于STL,C++标准程序库指的是什么?STL范围是什么?多谢,多谢!
作者: fibbery    时间: 2008-08-11 16:37
原帖由 yulc 于 2008-8-11 16:34 发表



你是指STL中的exception 类吧.
如果你想抛出这个类的对象,我记得是你先要声明一个该类的子类,像这样:
class MyException : public exception
{

};

然后你就可以 throw MyException();


对对!我是想使用exception以及其派生类,假设有需要使用该类跑出错误代码和错误信息,我该怎么做?谢谢!
作者: blueboy83    时间: 2008-08-11 16:39
哦 还没用过STL的异常类
作者: tyc611    时间: 2008-08-11 16:40
原帖由 fibbery 于 2008-8-11 16:35 发表
to tyc661:

我确实不知道C++标准程序库不等于STL,C++标准程序库指的是什么?STL范围是什么?多谢,多谢!

差不多你可以认为:C++标准库 = STL + “从C继承过来的库”
作者: DraculaW    时间: 2008-08-11 16:41
继承你想要继承的那个异常
重写what();
在异常的构造时 将你要打印的信息传入
作者: fibbery    时间: 2008-08-11 16:45
3.3.3 Throwing Standard Exceptions
You can throw standard exceptions inside your own library or program. All standard exception
classes that enable you to do this have only one parameter to create the exception: a string
(class string is described in Chapter 11) that will become the description returned by
what(). For example, the class logic_error is defined as follows:
namespace std {
class logic_error : public exception {
public:
explicit logic_error (const string& whatString);
};
}
The set of standard exceptions that provide this ability contains class logic_error and its
derived classes, class runtime_error and its derived classes, as well as class
ios_base::failure. Thus, you can't throw exceptions of the base class exception and any
exception class that is provided for language support.
To throw a standard exception, you simply create a string that describes the exception and use it
to initialize the thrown exception object:
string s;
...
throw out_of_range(s);
Implicit conversions from char* to string exist, so you can also use a string literal directly:
throw out_of_range("out_of_range exception (somewhere, somehow)";

3.3.4 Deriving Standard Exception ClassesAnother possibility for using the standard exception classes in your code is to define a special
exception class derived directly or indirectly from class exception. To do this, you must ensure
that the what() mechanism works.
The C++ Standard Library
dyne-book 34
The member function what() is virtual. So, one way to provide what() is to write your own
implementation of what():
namespace MyLib {
/* user-defined exception class
* derived from a standard class for exceptions
*/
class MyProblem : public std::exception {
public:
...
MyProblem(...) { //special constructor
}
virtual const char* what() const throw() {
//what() function
...
}
};
...
void f() {
...
//create an exception object and throw it
throw MyProblem(...);
...
}
}
Another way to provide the what() function is to derive your exception class from one of the
classes that have a string constructor for the what() argument:
namespace MyLib {
/* user-defined exception class
* - derived from a standard class for exceptions
* that has a constructor for the what() argument
*/
class MyRangeProblem : public std:ut_of_range {
public:
MyRangeProblem (const string& whatString)
: out_of_range(whatString) {
}
};
...
void f() {
...
//create an exception object by using a string constructor
and throw it
throw MyRangeProblem("here is my special range problem";
...
}
}
For examples that are part of a complete program, see class Stack on page 441 and class
Queue on page 450.

[ 本帖最后由 fibbery 于 2008-8-11 16:53 编辑 ]
作者: tyc611    时间: 2008-08-11 16:46
可以直接用标准库中exception的几个派生类,在头文件<stdexcept>中:
domain_error、invalid_argument、length_error、out_of_range、overflow_error、range_error、underflow_error

还可以自己从中派生异常类,可以在其中加入错误码等其它信息
作者: fibbery    时间: 2008-08-11 16:49
原帖由 tyc611 于 2008-8-11 16:40 发表

差不多你可以认为:C++标准库 = STL + “从C继承过来的库”


哦,STL是标准模板库




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2