我的老师要求班级修复此程序中的错误。实际上它似乎是一个糟糕的程序;我只是在工作表中输入它的确切方式,并得到了这个错误:
现在我刚刚更改了一些内容,但在运行时遇到此异常:Microsoft C ++异常:[rethrow]在内存位置0x00000000 ..
代码现在是这样的:(变量类名现在是西班牙语,对不方便感到抱歉)
#include <iostream>
#include <exception>
#include <stack>
using namespace std;
class EPilaVacia : public exception{
public:
const char* what() const throw(){
return "Error: Pila Vacía";
}
};
template <class T, int max=100>
class Pila{
private:
stack<T*> *pila;
int cont;
public:
Pila() : cont(0){
pila=new stack<T*>();
}
virtual void apilar( T* pt){
if(cont<max){
pila->push(pt); //respuesta 2
}
}
virtual void apilar(T t){
if(cont<max){
pila->push(&t); //respuesta 3
}
}
T tope() const throw (EPilaVacia){
if(cont>0){
pila->top(); //respuesta 4
}else{
throw ; //respuesta 5
}
}
T& desapilar() throw (EPilaVacia){
if(cont>0){
pila->pop(); //respuesta 6
}else{
throw ; //respuesta 7
}
}
int size() const{
return pila->size();
}
};
class Figura{
public:
virtual void print(){
cout<< "FIGURA" <<endl;
}
};
class Circulo : public Figura{
public:
void print(){
cout<<"CIRCULO"<<endl;
}
};
class Triangulo : public Figura{
public:
void print(){
cout<<"TRIANGULO"<<endl;
}
};
int main(){
Pila<Figura*> *pfiguras= new Pila<Figura*>();
pfiguras->apilar(new Circulo());
pfiguras->apilar(new Triangulo());
Pila<Figura*> pfiguras2(*pfiguras);
pfiguras->tope()->print();
pfiguras->desapilar();
pfiguras->tope()->print();
pfiguras->desapilar();
pfiguras2.tope()->print();
system("Pause");
return 0;
}
答案 0 :(得分:7)
从哪里开始?这有很多错误。
没有“using namespace std;”,它会使全局命名空间变得混乱。相反,使用std :: list,std :: cin等使用命名空间来标识特定对象或类。
在异常类中,不要编写自己的what()
方法。只需在构造函数中初始化基类。
class EPilaVacia : public std::exception
{
public:
EPilaVacia()
: std::exception("Error: Pila Vacía")
{
}
};
我认为Pila班只是一个学习练习。在现实生活中,你会使用std::stack
,而不是自己制作。
如果您使用列表实现堆栈,则不需要“max”参数。
不要动态分配列表,这很愚蠢。只是用
std::list<T*> ila;
您不需要“续”。使用ila.size();
不要使像apilar()这样的函数虚拟化。该列表是私有的,因此子类无法访问它,因此无法覆盖这些方法。此外,您没有虚拟析构函数,因此继承可能是一个坏主意。
void apilar(T t)是一场灾难。您通过值传递t,然后存储参数的地址,然后超出范围。该功能是不必要的,失去它。
不要在方法声明中加入“throw(EPilaVacia)”。没有编译器实现它,并且在新的C ++ 11标准中不推荐使用它。
在tope()中,使用ila.back(),而不是ila.pop_back()。
T tope() const
{
if(ila.empty())
{
throw EPilaVacia();
}
else
{
return *ila.back();
}
}
在desapilar()中,不要使用clear,因为它会清空堆栈。使用类似这样的东西
T& desapilar()
{
if(ila.empty())
{
throw EPilaVacia();
}
else
{
T *pt = ila.back();
ila.pop_back();
return *pt;
}
}
从不使用system("Pause");
使用std::cin.get();
永远不会删除使用new
分配的对象。你有内存泄漏。
可能还有更多,但这应该让你开始。 注意:我快速写下来了。上面可能有错误,所以检查我的代码,不要只是复制它。
答案 1 :(得分:3)
这个错误是否发生在"mystack=new stack<T>;"
行,因为这是我看到的唯一可能导致这种情况的行。原因是mystack定义为T *,而不是stack<T>
。当编译器尝试将新的stack<T>
分配给mystack时,它会看到mystack正在查找T *,并说“我不知道如何将stack<T>
变成T *”。
既然您已经修复了该错误,那么您将从nullptr异常中获得抛出。通常,通过在调试器下运行并查看哪个行导致程序运行不良,可以最好地解决这个问题。但是,通过检查,您似乎只是将两个东西推到堆栈上,然后尝试使用“top”来获得第三个:pfiguras2.tope()->print();
。
你也在泄露记忆,但迈克尔J的评论对于这个代码中更加挑剔,更少“使它不崩溃”的区域更好。