C++ 泛型堆栈类的异常安全代码
我正在尝试编写一个异常安全的通用堆栈。这就是我到目前为止所做的C++ 泛型堆栈类的异常安全代码,c++,exception,generics,c++11,C++,Exception,Generics,C++11,我正在尝试编写一个异常安全的通用堆栈。这就是我到目前为止所做的 #include <iostream> #include <memory> #include <exception> class stk_exception:public exception { virtual const char* what() const throw() { return "stack underflow"; } } stk_ex;
#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();
}
#包括
#包括
#包括
类stk_异常:公共异常
{
虚拟常量char*what()常量throw()
{
返回“堆栈下溢”;
}
}stk_ex;
模板
结构节点
{
T数据;
节点*下一步;
};
模板
类堆栈\u泛型
{
公众:
堆栈_generic():_头(nullptr){
}
无效推力(T x){
节点*temp(新节点());
温度->数据=x;
温度->下一步=_头;
_压头=温度;
}
void pop(){
如果(_head==nullptr){
投掷沙丁鱼;
}否则{
节点*温度=_头;
_头部=_头部->下一步;
删除临时文件;
返回;
}
}
T top(){
T x=T();
如果(_head==nullptr){
投掷沙丁鱼;
}否则{
返回头->数据;
}
}
私人:
节点*头;
};
int main()
{
堆栈(s),;
s、 推(1);
s、 推(2);
std::cout以下实现应该(几乎)是异常安全的:
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{};
}
}
void push(T x){
head=新节点{std::move(x),head};
}
T pop(无效){
若有(总目){
T结果{std::move(head->data)};
自动旧=头;
头部=头部->下一步;
删除旧的;
返回结果;
}否则{
cout最佳实践是使用std::shared\u 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();
}
#包括
#包括
#包括
模板
类节点
{
公众:
节点(T数据,std::shared\u ptr next)
:_数据(数据),_下一个(下一个)
{
}
T data()常量
{
返回数据;
}
std::shared_ptr next()常量
{
返回下一步;
}
私人:
T_数据;
std::共享\u ptr\u next;
};
模板
类堆栈\u泛型
{
公众:
堆栈_泛型()
:_head(nullptr)
{
}
无效推力(T x)
{
_head=std::使_共享(x,_head);
}
T pop()
{
如果(_head==nullptr){
抛出标准::下溢错误(“下溢”);
}否则{
标准::共享温度=_头;
_头=_头->下一步();
返回temp->data();
}
}
私人:
std::共享ptr头;
};
int main()
{
堆栈(s),;
s、 推(1);
s、 推(2);
STD::CUT 1。请不要使用“NULL”用于C++代码,使用“NulLPTR”相反。2.你的代码格式就像一张名片。如果看起来凌乱,那就是你的第一印象。哪一行?唯一的\u ptr在哪里?std::unique\u ptr
的默认复制构造函数和复制赋值运算符已被删除,因为它们不存在。要使用unique\u ptr
,你需要使用而不是复制。@ Flovdis: NulLPTR> /Cord>只是一个选项,如果代码只需要在C++ 11编译器上编译。但是,在这种情况下,我同意NulLPTR是更好的解决方案。也许另一种选择是检查C++版本,并使用<代码>定义旧版本的NulLPTR NULL/<代码>。code>unique\u ptr
也需要C++11,并且在这个问题上有一个C++11标记。+1用于提及单独的top
和pop
方法。使用单独的top
和pop
函数是std::stack
避免这个问题的方法。更喜欢std::make\u shared
而不是构建与new
@YoungJohn共享的好主意,让我来解决这个问题。谢谢。