2012-06-14 2 views
0

Мой учитель попросил класс исправить ошибку в этой программе. На самом деле это кажется дрянной программой; Я просто набрал его точно, как он находится на листе, и получил эту ошибку:C++ Устранение программных упражнений

Ну теперь я только что изменил некоторые вещи, но получаю это исключение во время выполнения: исключение Microsoft C++: [rethrow] в ячейке памяти 0x00000000. .

код теперь так: (переменная AN имена классов теперь на испанском языке, извините за inconviniences)

#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

Я вижу одну ошибку: вызов деструктора без уважительной причины. Кроме того, ваш учитель не должен говорить вам использовать 'system (« PAUSE »);'. – chris

+0

Да, действительно, система («пауза») появилась в качестве одной из вещей, которые нам нужно исправить. – dlvx

+1

Была ли это домашняя запись предыдущего студента? : -/(Я согласен с вашей «дерьмовой» оценкой.) – ildjarn

ответ

3

является ли эта ошибка происходит на линии "mystack=new stack<T>;", как это единственная линия, которую я вижу, что может вызвать это. Причиной этого является то, что мистика определяется как T *, а не stack<T>. Когда компилятор пытается назначить новый мистике, он видит, что мистика ищет T *, и говорит: «Я не знаю, как сделать stack<T> в T *».

Теперь, когда вы исправили эту ошибку, вы получаете бросок от исключения nullptr. Это было бы лучше всего решить, как правило, запустив это под отладчиком и увидев, какая строка заставляет вашу программу вести себя плохо. Однако при проверке кажется, что вы только нажимаете две вещи на стек, а затем пытаетесь использовать «верх», чтобы получить третью: pfiguras2.tope()->print();.

Вы также просачиваете память, но комментарий Майкла J намного лучше подходит для более nitpicky, менее «сделать это не крушить» области этого кода.

+0

Тет один и тот же – Attila

+0

Эй, я кое-что изменил, я только что отредактировал свой ответ – dlvx

+0

Обновлен мой ответ в ответ на ваши изменения. Это похоже на то, что лучше решить, если вы напишете стек с нуля, чтобы узнать, что это значит, но, похоже, ваши профессора хотят, чтобы вы захватили наследование. – Tawnos

7

С чего начать? Это много ошибок.

  1. Не имеет «использования пространства имен 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. Вам не нужно "cont". Использовать 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(), не используйте ясно, как это будет опустошить стек. Используйте что-то вроде этого

    T& desapilar() 
    { 
        if(ila.empty()) 
        { 
         throw EPilaVacia(); 
        } 
        else 
        { 
         T *pt = ila.back(); 
         ila.pop_back(); 
         return *pt; 
        } 
    } 
    
  12. NEVER использования system("Pause"); Использование std::cin.get();

  13. Объекты, которые вы распределили с new никогда не удаляются. У вас есть утечка памяти.

Есть, вероятно, больше, но это должно заставить вас начать. Примечание: Я быстро нацарапал это. Вероятно, есть ошибки, поэтому проверьте мой код, не просто скопируйте его.