程序保持调用意外和终止函数

时间:2015-12-17 03:46:06

标签: c++ exception

// main.cpp
#include <iostream>
#include "otevector.h"
#include "poikkeus.h"

using namespace std;
using otecpp_otevector::OteVector;
using otecpp_poikkeus::asetaKasittelijat;
using otecpp_poikkeus::LaitonIndeksi;
using otecpp_poikkeus::OdottamatonPoikkeus;

namespace 
{
  void luoPoikkeus(OteVector<int> &t, int k) throw(LaitonIndeksi, OdottamatonPoikkeus) {
    if(k == 0) {
      t[4] = 10;   
    }
    else if(k == 1) {
      cout << t[-2]; 
    }
    else if(k == 2) {
      throw -500;     
    }
    else {
      throw 9.5;  
    }
  }
}

int main() {
  OteVector<int> t(4);
  asetaKasittelijat();  
  for(int kierros = 0; kierros < 4; ++kierros) {
    try {
      luoPoikkeus(t, kierros);
    }
    catch(LaitonIndeksi &li) {
    cout << li.what() << '\n';
    }
    catch(OdottamatonPoikkeus &op) {
    cout << op.what() << '\n';
    }
  }
}


// Exception class (poikkeus.cpp)
#include <string>
#include "poikkeus.h"
#include <cstddef>
#include <iostream>
#include <cstdlib>
#include <exception>
#include <sstream>
#include <string.h>
using otecpp_poikkeus::LaitonIndeksi;
using otecpp_poikkeus::OdottamatonPoikkeus;
using namespace std;
namespace otecpp_poikkeus
{
    LaitonIndeksi::LaitonIndeksi(ptrdiff_t i)
    {
        ostringstream oss;
        oss << "Laiton indeksi: ";
        oss << i;
        this->merkkijono = oss.str();
        cout << this->merkkijono << endl;
    }
    const char* LaitonIndeksi::what() const throw()
    {
        return merkkijono.c_str();
    }
    OdottamatonPoikkeus::OdottamatonPoikkeus(const string &viesti)
    {
        this->merkkijono = "Odottamaton poikkeus: " + viesti;
    }
    const char* OdottamatonPoikkeus::what() const throw()
    {
        return merkkijono.c_str();
    }
    void asetaKasittelijat()
    {
    set_unexpected(odottamaton);
    set_terminate(terminatea);

    }
    void odottamaton()
    {
        try {
             throw;
        }catch (int i) {
          throw new LaitonIndeksi(i);
            } catch(const char* s) {
             cout << "string poikkeus: " << s;
         } catch (...) {
        cout << "Ohjelma lopetetaan odottamattoman poikkeuksen vuoksi" << endl; 
        terminate();
        }
    }
    void terminatea()
    {
        cout << "Kutsuttiin omaa terminate-funktiota";
        exit(EXIT_SUCCESS);
    }

}


 // Exception header (poikkeus.h)


#ifndef POIKKEUS_H
#define POIKKEUS_H
#include <iostream>
#include <exception>
#include <cstddef>
#include <string>
namespace otecpp_poikkeus
{
    class LaitonIndeksi : public std::exception
    {
        std::string merkkijono;
    public:
        const char* what() const throw();
        LaitonIndeksi(ptrdiff_t i);
        ~LaitonIndeksi() throw() {}

    };
    class OdottamatonPoikkeus : public std::exception
    {
        std::string merkkijono;
    public:
        const char* what() const throw();
        OdottamatonPoikkeus(const std::string &viesti);
        ~OdottamatonPoikkeus() throw() { }

    };
    void asetaKasittelijat();
    void odottamaton();
    void terminatea();

}


#endif



//vector like class


#ifndef OTEVECTOR_H
#define OTEVECTOR_H
#include <iostream>
#include <cstddef>
#include <algorithm>
#include <string.h>
#include "poikkeus.h"
#include <exception>
using otecpp_poikkeus::LaitonIndeksi;
using otecpp_poikkeus::OdottamatonPoikkeus;
namespace otecpp_otevector {
    template<typename T>
    class OteVector
    {


    public:
        ptrdiff_t koko;
        T *taulu;

        OteVector(unsigned int koko);

        ~OteVector();
        T & operator[](ptrdiff_t i) throw(LaitonIndeksi);

        const T & operator[](ptrdiff_t i) const throw(LaitonIndeksi);

        OteVector(const OteVector<T> &v);

        OteVector<T>& operator=(const OteVector<T>& v);

    };
    template<typename T>
    OteVector<T>::OteVector(unsigned int koko)
    {
        this->koko = koko;
        this->taulu = new T[koko];
    }
    template<typename T>
    OteVector<T>::~OteVector()
    {
        delete[] taulu;
}
    template<typename T>
    T & OteVector<T>::operator[](ptrdiff_t i) throw(LaitonIndeksi)
    {
        if (i < 0 || i > this->koko - 1)
            {
             throw new LaitonIndeksi(i);
            }
           return taulu[i];

    }

    template<typename T>
    const T & OteVector<T>::operator[](ptrdiff_t i) const throw(LaitonIndeksi)
    {
        if (i < 0 || i > this->koko - 1)
            {
              throw new LaitonIndeksi(i);
            }
              return taulu[i];
        }
    template<typename T>
    OteVector<T>::OteVector(const OteVector<T> &v)
    {
        this->koko = v.koko;
        taulu = new T[v.koko];
        for (int i = 0; i < koko; i++)
        {
            this->taulu[i] = v.taulu[i];
        }
    }
    template<typename T>
    OteVector<T>& OteVector<T>::operator=(const OteVector<T>& v)
    {
        if (this->taulu == v.taulu) {
            return *this;
        }
        this->koko = v.koko;
        taulu = (new T[v.koko]);
        for (int i = 0; i < koko; i++)
        {
            this->taulu[i] = v.taulu[i];
        }
        return *this;
    }
}
#endif // OTEVECTOR_H

很抱歉把整个代码放在这里,但我试图找到问题这么久,我不知道这是什么问题。所以问题在于主要功能如果(k == 0)(主要给我,所以我不能改变它)。当程序调用otevector类的[]操作符时,它不向控制台写入“LaitonIndeksi”消息,它只是移动到意外的方法(odottamaton()),之后它只是终止程序whit终止方法。为什么这些异常不起作用,程序才会终止?

2 个答案:

答案 0 :(得分:2)

向量有4个元素,索引为0,1,2和3.当k为0时,代码将值赋给t[4]。那不好。

答案 1 :(得分:1)

您尝试编写执行绑定检查的代码:

if (i < 0 || i > this->koko - 1)
{
    throw new LaitonIndeksi(i);
}

但是你抛出指向异常的指针,即LaitonIndeksi*。相应的catch子句如下所示:

catch (LaitonIndeksi &li) {
    cout << li.what() << '\n';
}
catch (OdottamatonPoikkeus &op) {
    cout << op.what() << '\n';
}

因此LaitonIndeksi*未处理,并且调用了意外的处理程序。

你应该做的只是抛出异常:

throw LaitonIndeksi(i);