0

我的老师要求全班纠正这个程序中的错误。实际上,这似乎是一个糟糕的程序;我只是准确地输入了它在工作表中的样子,并得到了这个错误:

好吧,现在我刚刚更改了一些东西,但是在运行时得到了这个异常:Microsoft C++ exception: [rethrow] at memory location 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;
}
4

2 回答 2

7

从哪儿开始?这有很多错误。

  1. 没有“using namespace std;”,它会使全局命名空间变得混乱。而是使用 std::list、std::cin 等使用命名空间来标识特定对象或类。

  2. 在异常类中,不要编写自己的what()方法。只需在构造函数中初始化基类。

    class EPilaVacia : public std::exception
    {
    public:
        EPilaVacia()
        : std::exception("Error: Pila Vacía")
        {
        }
    };
    
  3. 我认为 Pila 课程只是一个学习练习。在现实生活中,您会使用std::stack,而不是自己制作。

  4. 如果您使用列表实现堆栈,则不需要“max”参数。

  5. 不要动态分配列表,这很愚蠢。只需使用 std::list<T*> ila;

  6. 你不需要“继续”。利用ila.size();

  7. 不要将 apilar() 之类的函数设为虚拟函数。该列表是私有的,因此子类无法访问它,因此无法覆盖方法。此外,您没有虚拟析构函数,因此继承可能不是一个好主意。

  8. void apilar(T t) 是一场灾难。您按值传递 t,然后存储参数的地址,然后超出范围。该功能是不必要的,失去它。

  9. 不要在方法声明中添加“throw (EPilaVacia)”。没有编译器实现它,并且在新的 C++11 标准中已弃用。

  10. 在 tope() 中,使用 ila.back(),而不是 ila.pop_back()。

    T tope() const 
    {
        if(ila.empty())
        {
            throw EPilaVacia();
        }
        else
        {
            return *ila.back();
        }
    }
    
  11. 在 desapilar() 中,不要使用 clear,因为它会清空堆栈。使用这样的东西

    T& desapilar()
    {
        if(ila.empty())
        {
            throw EPilaVacia();
        }
        else
        {
            T *pt = ila.back();
            ila.pop_back();
            return *pt;
        }
    }
    
  12. 永远system("Pause"); 不要使用std::cin.get();

  13. 您分配的对象new永远不会被删除。你有内存泄漏。

可能还有更多,但这应该让你开始。笔记:我很快就草草写下来了。上面可能有错误,所以检查我的代码,不要只是复制它。

于 2012-06-14T01:56:53.483 回答
3

此错误是否在线发生,"mystack=new stack<T>;"因为这是我看到的唯一可能导致此错误的行。原因是 mystack 被定义为 T*,而不是stack<T>. 当编译器尝试将 new 分配stack<T>给 mystack 时,它会看到 mystack 正在寻找 T*,并说“我不知道如何制作stack<T>T*”。

现在您已经修复了该错误,您将得到一个来自 nullptr 异常的抛出。通常,最好通过在调试器下运行它并查看是哪一行导致您的程序表现不佳来解决这个问题。但是,通过检查,您似乎只是将两个东西压入堆栈,然后尝试使用“top”来获得第三个:pfiguras2.tope()->print();.

您也在泄漏内存,但 Michael J 的评论在这段代码中更挑剔、更少“让它不会崩溃”的区域中表现得更好。

于 2012-06-14T00:24:10.527 回答