cla*_*ius 3 c++ generics exception c++11
我正在尝试编写一个异常安全的通用堆栈.这就是我到目前为止所做的.
#include <iostream>
#include <memory>
#include <exception>
class stk_exception:public exception 
{
    virtual const char* what() const throw()
    {
        return "stack underflow";
    }
} stk_ex;
template <class T>
struct node
{
    T data;
    node<T> *next;
};
template <class T>
class stack_generic
{
public:
    stack_generic() : _head(nullptr) {
    }
    void push(T x) {
        node<T> *temp(new node<T>());
        temp->data = x;
        temp->next = _head;
        _head = temp;
    }            
    void pop() {
        if (_head == nullptr) {
            throw stk_ex;                
        } else {
            node<T> *temp = _head;
            _head = _head->next;
            delete temp;
            return;
        }
    }
    T top() {
        T x = T();
        if (_head == nullptr) {
            throw stk_ex;                
        } else {
           return _head->data;
        }
    }
private:
    node<T> *_head;
};
int main()
{
    stack_generic<int> s;
    s.push(1);
    s.push(2);
    std::cout << s.top();
    s.pop();
    std::cout << s.top();
    s.pop();
}
我可以使用STL列表/向量来实现RAII,但我想使用原始指针.因此,当我使用unique_ptr将头指针包装在堆栈中时,它会抛出一个编译错误"对于调用unique_ptr,default_delete没有匹配的函数.这里有什么问题?有人可以建议我该怎样做才能使这个类异常安全吗?谢谢!
编辑:为下溢添加了异常处理.定义了单独的top和pop方法
以下实现应该(几乎)异常安全:
void push(T x) {
    head = new node<T>{std::move(x), head};
}
T pop(void) {
    if (head) {
        T result{std::move(head->data)};
        auto old = head;
        head = head->next;
        delete old;
        return result;
    } else {
        cout << "underflow!";
        return T{};
    }
}
这段代码的唯一问题是return result.通常,此操作可能会抛出异常,在这种情况下,调用者会看到异常,但堆栈仍然会发生更改.
您可以通过将函数分成两个函数来避免此问题.第一个函数返回top元素,第二个函数删除它.
| 归档时间: | 
 | 
| 查看次数: | 417 次 | 
| 最近记录: |