Sugauti tam tikras išimtis? - C ++

Aš dalyvauju savo pirmojoje C + + programavimo klasėje ir dirbau projekte, kuriame turime sukurti keletą pasirinktinių išimčių klasių, o tada viename iš mūsų įvykių tvarkytojų naudokite try/catch kad juos tinkamai tvarkytume.

Mano klausimas yra toks: kaip aš galiu sugauti keletą naudotojo išimčių mano try/catch ? GetMessage() yra pasirinktinis metodas mano išimčių klasėse, kuri grąžina išimtį kaip std::string . Žemiau aš įtraukiau visą atitinkamą kodą iš savo projekto.

Dėkojame už pagalbą!

pabandykite / sugauti bloką


  // This is in one of my event handlers, newEnd is a wxTextCtrl try { first.ValidateData(); newEndT = first.ComputeEndTime(); *newEnd << newEndT; } catch (// don't know what do to here) { wxMessageBox(_(e.GetMessage()), _("Something Went Wrong!"), wxOK | wxICON_INFORMATION, this);; } 

ValidateData metodas ()


 void Time::ValidateData() { int startHours, startMins, endHours, endMins; startHours = startTime / MINUTES_TO_HOURS; startMins = startTime % MINUTES_TO_HOURS; endHours = endTime / MINUTES_TO_HOURS; endMins = endTime % MINUTES_TO_HOURS; if (!(startHours <= HOURS_MAX  startHours >= HOURS_MIN)) throw new HourOutOfRangeException("Beginning Time Hour Out of Range!"); if (!(endHours <= HOURS_MAX  endHours >= HOURS_MIN)) throw new HourOutOfRangeException("Ending Time Hour Out of Range!"); if (!(startMins <= MINUTE_MAX  startMins >= MINUTE_MIN)) throw new MinuteOutOfRangeException("Starting Time Minute Out of Range!"); if (!(endMins <= MINUTE_MAX  endMins >= MINUTE_MIN)) throw new MinuteOutOfRangeException("Ending Time Minute Out of Range!"); if(!(timeDifference <= P_MAX  timeDifference >= P_MIN)) throw new PercentageOutOfRangeException("Percentage Change Out of Range!"); if (!(startTime < endTime)) throw new StartEndException("Start Time Cannot Be Less Than End Time!"); } 

Tik viena iš mano pasirinktinių išimčių klasių, kitos turi tokią pačią struktūrą


 class HourOutOfRangeException { public: // param constructor // initializes message to passed paramater // preconditions - param will be a string // postconditions - message will be initialized // params a string // no return type HourOutOfRangeException(string pMessage) : message(pMessage) {} // GetMessage is getter for var message // params none // preconditions - none // postconditions - none // returns string string GetMessage() { return message; } // destructor ~HourOutOfRangeException() {} private: string message; }; 
40
25 марта '10 в 6:37 2010-03-25 06:37 Alexas yra nustatytas kovo 25d. 10, 06:37 2010-03-25 06:37
@ 7 atsakymai

Jei turite kelių tipų išimtis ir manoma, kad yra išimčių hierarchija (ir visi gauti viešai iš std::exception poklasio), pradėkite nuo konkrečių ir pereikite prie bendresnių:

 try { // throws something } catch ( const MostSpecificException e ) { // handle custom exception } catch ( const LessSpecificException e ) { // handle custom exception } catch ( const std::exception e ) { // standard exceptions } catch ( ... ) { // everything else } 

Kita vertus, jei jus domina tik klaidos pranešimas - throw tą pačią išimtį, pasakyti „ std::runtime_error su skirtingais pranešimais ir tada catch kad:

 try { // code throws some subclass of std::exception } catch ( const std::exception e ) { std::cerr << "ERROR: " << e.what() << std::endl; } 

Taip pat nepamirškite - užversti vertę, užkabinkite nuorodą [const].

49
25 марта '10 в 6:51 2010-03-25 06:51 Atsakymą pateikė Nikolajus Fetissovas kovo 25 d. 10 val. 6:51 2010-03-25 06:51

Turite sukurti pagrindinę išimties klasę ir gauti visas konkrečias išimtis:

 class BaseException { }; class HourOutOfRangeException : public BaseException { }; class MinuteOutOfRangeException : public BaseException { }; 

Tada galite sugauti visus juos viename sugavimo bloke:

 catch (const BaseException e) { } 

Jei norite skambinti „ GetMessage , turite:

  • įdėti šią logiką į „ BaseException arba
  • Padarykite „ GetMessage virtualaus nario funkciją „ BaseException ir panaikinkite ją kiekvienoje iš išvestinių išimčių klasėse.

Galbūt taip pat manote, kad jūsų išimtys atsiranda dėl vienos iš standartinių bibliotekos išimčių, pvz., std::runtime_error ir naudokite nario funkciją idiomatiškai, o ne vietoj „ GetMessage() .

9
25 марта '10 в 6:40 2010-03-25 06:40 atsakė James McNellis, kovo 10 d., 10 val., 2010-03-25 06:40

Spausdinkite visas išimtis iš bendros bazinės klasės BaseException , turinčio virtualų metodą GetMessage() .

Tada catch(const BaseException e) .

1
25 марта '10 в 6:39 2010-03-25 06:39 Atsakymą pateikė Jesse Beder , kovo 25 d. 10 val. 6:39 2010-03-25 06:39

Šiandien turėjau panašią problemą, tačiau paaiškėja, kad man nereikia sprendimo, kad išspręstumėte savo problemą. Sąžiningai, aš negalėjau galvoti apie realius naudojimo atvejus (registravimą?), Ir aš nerado daug reikšmės jo kodui.

Bet kokiu atveju tai yra požiūris į tipų sąrašus (reikalingas C ++ 11). Manau, kad šio požiūrio privalumas yra tas, kad nereikia turėti bendros bazinės klasės vartotojų išimčių (išskyrus std :: išimtį, galbūt?). Kitaip tariant, tai nėra užuomina į jūsų išimčių hierarchiją.

Gali būti tam tikrų subtilių klaidų, apie kurias aš nežinau.

 #include <type_traits> #include <exception> /// Helper class to handle multiple specific exception types /// in cases when inheritance based approach would catch exceptions /// that are not meant to be caught. /// /// If the body of exception handling code is the same /// for several exceptions, /// these exceptions can be joined into one catch. /// /// Only message data of the caught exception is provided. /// /// @tparam T Exception types. /// @tparam Ts At least one more exception type is required. template <class T, class... Ts> class MultiCatch; /// Terminal case that holds the message. /// ``void`` needs to be given as terminal explicitly. template <> class MultiCatch<void> { protected: explicit MultiCatch(const char* err_msg) : msg(err_msg) {} const char* msg; }; template <class T, class... Ts> class MultiCatch : public MultiCatch<Ts...> { static_assert(std::is_base_of<std::exception, T>::value, "Not an exception"); public: using MultiCatch<Ts...>::MultiCatch; /// Implicit conversion from the guest exception. MultiCatch(const T error) : MultiCatch<Ts...>(error.what()) {} // NOLINT /// @returns The message of the original exception. const char* what() const noexcept { return MultiCatch<void>::msg; } }; /// To avoid explicit ``void`` in the type list. template <class... Ts> using OneOf = MultiCatch<Ts..., void>; /// Contrived example. void foo() { try { bar(); // May throw three or more sibling or unrelated exceptions. } catch (const OneOf<IOError, OutOfMemory> err) { log() << "External failure: " << err.what(); throw; // Throw the original exception. } } 
0
11 сент. atsakymas suteiktas Olzhas Rakhimov 11 sep . 2016-09-11 15:15 '16 at 15:15 2016-09-11 15:15

Aš susidūriau su ta pačia problema, ir tai aš baigiau:

  std::shared_ptr<MappedImage> MappedImage::get(const std::string  image_dir, const std::string  name, const Packet::Checksum  checksum) { try { return std::shared_ptr<MappedImage>(images_.at(checksum)); } catch (std::out_of_range) { } catch (std::bad_weak_ptr) { } std::shared_ptr<MappedImage> img = std::make_shared<MappedImage>(image_dir, name, checksum); images_[checksum_] = img; return img; } 

Mano atveju, funkcija grąžinama, kai ji negauna išimties. Taigi, aš neturiu nieko daryti viduje sužvejotų žuvų, bet aš galiu atlikti darbą ne bandant.

0
28 янв. Goswin von Brederlow atsakymas sausio 28 d 2019-01-28 16:15 '19, 16:15 pm 2019-01-28 16:15

Kai šablonai negali, makrokomandos išsaugo dieną. Sprendimas priimtas iš „ Boost“ . Jis virsta iki 7 kodų eilučių.

 /// @file multicatch.hpp #include <boost/preprocessor/variadic/to_list.hpp> #include <boost/preprocessor/list/for_each.hpp> /// Callers must define CATCH_BODY(err) to handle the error, /// they can redefine the CATCH itself, but it is not as convenient. #define CATCH(R, _, T) \ catch (T  err) { \ CATCH_BODY(err) \ } /// Generates catches for multiple exception types /// with the same error handling body. #define MULTICATCH(...) \ BOOST_PP_LIST_FOR_EACH(CATCH, _, BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)) // end of file multicatch.hpp /// @file app.cc #include "multicatch.hpp" // Contrived example. /// Supply the error handling logic. #define CATCH_BODY(err) \ log() << "External failure: " << err.what(); \ throw; void foo() { try { bar(); // May throw three or more sibling or unrelated exceptions. } MULTICATCH(IOError, OutOfMemory) } #undef CATCH_BODY 
0
12 сент. Olzhas Rakhimov atsakymas rugsėjo 12 d 2016-09-12 01:32 '16 at 1:32 2016-09-12 01:32

 #include <iostream> void test(int x)' { try{ if(x==1) throw (1); else if(x==2) throw (2.0); } catch(int a) { cout<<"It Integer"; } catch(double b) { cout<<"it Double"; } } int main(){ cout<<" x=1"; test(1); cout<<"X=2"; test(2.0); return 0; }' 
-3
27 февр. atsakymas pateikiamas Umet Ale 27 vasario mėn. 2018-02-27 14:33 '18 at 14:33 201-02-27 14:33

Kiti klausimai apie „ žymes arba užduoti klausimą