C ++修复编程练习

时间:2012-06-14 00:13:27

标签: c++

我的老师要求班级修复此程序中的错误。实际上它似乎是一个糟糕的程序;我只是在工作表中输入它的确切方式,并得到了这个错误:

现在我刚刚更改了一些内容,但在运行时遇到此异常: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;
}

2 个答案:

答案 0 :(得分: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分配的对象。你有内存泄漏。

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

答案 1 :(得分:3)

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

既然您已经修复了该错误,那么您将从nullptr异常中获得抛出。通常,通过在调试器下运行并查看哪个行导致程序运行不良,可以最好地解决这个问题。但是,通过检查,您似乎只是将两个东西推到堆栈上,然后尝试使用“top”来获得第三个:pfiguras2.tope()->print();

你也在泄露记忆,但迈克尔J的评论对于这个代码中更加挑剔,更少“使它不崩溃”的区域更好。