// 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终止方法。为什么这些异常不起作用,程序才会终止?
答案 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);