加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 通用堆栈类的异常安全代码

发布时间:2020-12-16 09:51:28 所属栏目:百科 来源:网络整理
导读:我正在尝试编写一个异常安全的通用堆栈.这就是我到目前为止所做的. #include iostream#include memory#include exceptionclass stk_exception:public exception { virtual const char* what() const throw() { return "stack underflow"; }} stk_ex;template
我正在尝试编写一个异常安全的通用堆栈.这就是我到目前为止所做的.

#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方法

解决方法

最佳做法是使用std :: shared_ptr.您可以像这样实现类:

#include <iostream>
#include <memory>
#include <exception>


template <class T>
class node
{
public:
    node(T data,std::shared_ptr<node<T>> next)
        : _data(data),_next(next)
    {
    }

    T data() const
    {
        return _data;
    }

    std::shared_ptr<node<T>> next() const
    {
        return _next;
    }

private:
    T _data;
    std::shared_ptr<node<T>> _next;
};


template <class T>
class stack_generic
{
public:
    stack_generic()
        : _head(nullptr)
    {
    }

    void push(T x)
    {
        _head = std::make_shared<node<T>>(x,_head);
    }

    T pop()
    {
        if (_head == nullptr) {
            throw std::underflow_error("underflow");
        } else {
            std::shared_ptr<node<T>> temp = _head;
            _head = _head->next();
            return temp->data();
        }
    }

private:
    std::shared_ptr<node<T>> _head;
};


int main()
{
    stack_generic<int> s;
    s.push(1);
    s.push(2);
    std::cout << s.pop();
    std::cout << s.pop();
}

请注意以下事项:

>使用命名空间std;是不好的做法.>对现代C程序使用nullptr而不是NULL.>使用下溢的异常来创建已定义的行为.>在节点上使用访问器方法来创建只读对象.>为节点使用构造函数.>使用例如std :: shared_ptr自动释放数据.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读