C++-Programmierung/ Eine Matrix-Bibliothek – mitrax/ Klassen für die Ausnahmebehandlung


Die Fehlerklassen stehen in der Datei exception.hpp. mitrax stellt einen eigenen Namensbereich namens error für seine Fehlerklassen bereit. Die Fehler teilen sich in logische Fehler (von std::logic_error abgeleitet) und Bereichsfehler (von std::out_of_range abgeleitet) auf. Wenn eine mitrax-Funktion einen Fehler wirft, dann übergibt sie einen Text, anhand dessen sie identifiziert werden kann und, sofern vorhanden, die wesentlichen Informationen, die zu der Ausnahme geführt haben. Die Fehlerklassen generieren daraus jeweils einen passenden Standardtext. Da der generierte Text an den Basisklassenkonstruktor hoch gereicht wird, muss die Generierung nötigenfalls von einer privaten statischen Funktion ausgeführt werden. Viel mehr gibt es zu den Fehlerklassen eigentlich nicht zu sagen. Sie sehen wie Folgt aus.

class access: public std::out_of_range{
public:
    explicit access(std::string const& what):std::out_of_range(what){}
    explicit access(char const* what):std::out_of_range(what){}
};


class row_access: public access{
public:
    template < typename SizeType >
    row_access(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& row_number
    ):
        access(make_text(text, size, row_number))
        {}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& row_number
    ){
        std::ostringstream error;
        error << text << ": Dimension(" << size.rows() << ", " << size.columns()
            << "): access in row " << row_number << " not allowed";
        return error.str();
    }
};


class column_access: public access{
public:
    template < typename SizeType >
    column_access(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& column_number
    ):
        access(make_text(text, size, column_number))
        {}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& size,
        SizeType const& column_number
    ){
        std::ostringstream error;
        error << text << ": Dimension(" << size.rows() << ", " << size.columns()
            << "): access in column " << column_number << " not allowed";
        return error.str();
    }
};


class data_size: public std::logic_error{
public:
    template < typename SizeType, typename Container >
    data_size(std::string const& text, dimension< SizeType > const& size, Container const& data):
        std::logic_error(make_text(text, size, data))
        {}

private:
    template < typename SizeType, typename Container >
    static std::string const make_text(
        std::string const& text, mitrax::dimension< SizeType > const& size, Container const& data
    ){
        std::ostringstream error;
        error << text << ": Dimension(" << size.rows() << ", " << size.columns()
            << ") not compatible with data-size " << data.size();
        return error.str();
    }
};


class dimension: public std::logic_error{
public:
    explicit dimension(std::string const& what):std::logic_error(what){}
    explicit dimension(char const* what):std::logic_error(what){}
};


class dimension_unequal: public dimension{
public:
    template < typename SizeType >
    dimension_unequal(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ):
        dimension(make_text(text, lhs, rhs)){}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ){
        std::ostringstream error;
        error << text << ": lhs.dimension(" << lhs.rows() << ", " << lhs.columns()
            << ") != rhs.dimension(" << rhs.rows() << ", " << rhs.columns() << ")";
        return error.str();
    }
};


class dimension_incompatible: public dimension{
public:
    template < typename SizeType >
    dimension_incompatible(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ):
        dimension(make_text(text, lhs, rhs)){}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text,
        mitrax::dimension< SizeType > const& lhs,
        mitrax::dimension< SizeType > const& rhs
    ){
        std::ostringstream error;
        error << text << ": lhs.dimension(" << lhs.rows() << ", " << lhs.columns()
            << "), rhs.dimension(" << rhs.rows() << ", " << rhs.columns() << ")";
        return error.str();
    }
};


class not_quadratic: public dimension{
public:
    template < typename SizeType >
    not_quadratic(std::string const& text, mitrax::dimension< SizeType > const& dim):
        dimension(make_text(text, dim)){}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text, mitrax::dimension< SizeType > const& dim
    ){
        std::ostringstream error;
        error << text << ": dimension(" << dim.rows() << ", " << dim.columns() << ")";
        return error.str();
    }
};


class singular_matrix: public std::logic_error{
public:
    explicit singular_matrix(std::string const& what):std::logic_error(what){}
    explicit singular_matrix(char const* what):std::logic_error(what){}
};


class size_unequal: public std::logic_error{
public:
    template < typename SizeType >
    size_unequal(std::string const& text, SizeType const& lhs, SizeType const& rhs):
        std::logic_error(make_text(text, lhs, rhs)){}

private:
    template < typename SizeType >
    static std::string const make_text(
        std::string const& text, SizeType const& lhs, SizeType const& rhs
    ){
        std::ostringstream error;
        error << text << ": " << lhs << " != " << rhs;
        return error.str();
    }
};

Somit sind Ihnen alle Fehler bekannt, die von mitrax geworfen werden können. Einige der Stelle, an denen dies geschielt haben Sie in den letzten Kapiteln schon kennen gelernt, die meisten Ausnahmen werden jedoch bei Berechnungen geworfen. Wenn Sie also als Benutzer neue Berechnungen einführen, dann ist es nicht unwahrscheinlich, dass Sie auch weitere Fehlerklassen hinzufügen müssen. Sofern diese eine Verwandtschaft mit einer der hier bereits existierenden Klassen aufweisten ist es natürlich sinnvoll, von dieser abzuleiten.