Afhandeling van uitzonderingen in C++ Terminate aangeroepen na het gooien van een instantie van ‘char const*’

Fout: Beëindig aangeroepen na het gooien van een instantie van ‘char const*’

toepassing beëindigen is vereist dat de Runtime deze op een ongebruikelijke manier beëindigt. Neem contact op met het ondersteuningsteam van de applicatie.

Ik weet niet zeker waardoor de compiler crasht als ik dit doe. Om het even welke ideeën? Een beetje nieuw in programmeren.

#include <iostream>
#include <iomanip>
using namespace std;
//Template for Maximum
template <class X>
X Maximum(X arg1, X arg2)
{
    if (arg1 > arg2)
        return arg1;
    else
        return arg2;
}
//Template for Minimum
template <class M>
M Minimum(M arg1, M arg2)
{
    if (arg1 > arg2)
        return arg2;
    else
        return arg1;
}
/* Template for Divide(D arg1, D arg2) arg1: the dividend arg2: the divisor Description: 
Divides arg1 by arg2. If arg2 equals zero then an exception is thrown. */
template <class D>
D Divide(D arg1, D arg2)
{
    if (arg2 == 0) {
        throw "You cannot devide by zero! ";
    }
    return (arg1 / arg2);
}
int main()
{
    int a, b;
    float c, d;
    double e, f;
    a = 2;
    b = 22;
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(a, b) << "\tmax: " << Maximum(a, b) << endl;
    c = 4.7f;
    d = 2.97f;
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(c, d) << "\tmax: " << Maximum(c, d) << endl;
    e = 387.78;
    f = 387.7798;
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(e, f) << "\tmax: " << Maximum(e, f) << endl;
    e = 40;
    f = 0;
    try {
        cout << setprecision(4) << fixed << showpoint << "Divide: " << e << '/' << f << " = " << Divide(e, f) << endl;
    }
    catch (string exceptionString) {
        cout << exceptionString;
    }
    system("pause");
    return 0;
}

Antwoord 1, autoriteit 100%

Een letterlijke tekenreeks is geen std::string. Je gooit de eerste, maar probeert de laatste te vangen. Ondanks het feit dat een std::stringopgebouwd kan zijn uit een letterlijke tekenreeks, zal dit niet gebeuren in een catch-clausule. De conversies die zijn toegestaan ​​in een catch-clausule worden beschreven in [behalve.handle] /3:

Een handler is een match voor een exception-object van het type E als:

  • De behandelaar is van het type cv T of cv T& en E en T van hetzelfde type zijn (waarbij de cv-kwalificaties op het hoogste niveau worden genegeerd), of
  • de behandelaar is van het type cv T of cv T& en T is een ondubbelzinnige openbare basisklasse van E, of
  • de handler is van het type cv T of const T& waarbij T een aanwijzer of aanwijzer naar het type lid is en E een aanwijzer of aanwijzer naar het type lid is
    dat kan worden omgezet in T door een of meer van

    • een standaard aanwijzerconversie zonder conversies naar verwijzingen naar privé- of beschermde of dubbelzinnige klassen
    • een functieaanwijzerconversie
    • een kwalificatieconversie, of
  • de handler is van het type cv T of const T& waarbij T een pointer is of een pointer naar het type lid en E is std​::​nullptr_t.

En geen van beide was van toepassing op het geval van letterlijke -> std::stringconversie.

Wat er uiteindelijk toe leidt dat die uitzondering niet wordt afgevangen, en dat de runtime std::terminateaanroept zoals wordt verondersteld te gebeuren met niet-afgevangen uitzonderingen.

Over het algemeen is het het beste om een speciaal uitzonderingstype te genereren (dat deel kan uitmaken van een hiërarchie), zodat de naam van het type de fout die is opgetreden, doorgeeft. Dit maakt het mogelijk om de fout op meer robuuste manieren af te handelen, als een handler (of een set handlers) moet worden geschreven.

Als u om de een of andere reden de standaardpraktijk niet wilt volgen, moet u ervoor zorgen dat de conversie een van de in de bovenstaande opsommingstekens is. U kunt ofwel:

  1. Gooi een std::stringletterlijke, zoals "You cannot devide by zero!"s(let op het achtervoegsel s).
  2. Vang een const char*.

Other episodes