Saat mendesain pustaka C ++ 'serius' pertama saya, saya bertanya pada diri sendiri:
Apakah gaya yang baik untuk mendapatkan pengecualian dari std::exception
dan keturunannya?
Bahkan setelah membaca
- Merancang kelas pengecualian
- Apa yang dimaksud dengan 'jumlah yang baik' untuk diterapkan untuk perpustakaan saya?
Aku masih tidak yakin. Karena, selain praktik umum (tapi mungkin tidak baik), saya akan berasumsi, sebagai pengguna perpustakaan, bahwa fungsi perpustakaan akan melempar std::exception
hanya ketika fungsi perpustakaan standar gagal dalam implementasi perpustakaan, dan tidak dapat berbuat apa-apa. Tapi tetap saja, ketika menulis kode aplikasi, bagi saya itu sangat nyaman, dan juga IMHO tampan hanya melempar std::runtime_error
. Selain itu, pengguna saya juga dapat mengandalkan antarmuka minimum yang ditentukan, seperti what()
atau kode.
Dan misalnya, pengguna saya memberikan argumen yang salah, apa yang lebih nyaman, daripada melempar std::invalid_argument
, bukan? Jadi dikombinasikan dengan penggunaan std :: exception yang umum saya lihat di kode lain: Mengapa tidak melangkah lebih jauh dan berasal dari kelas pengecualian khusus Anda (mis. Lib_foo_exception) dan juga dari std::exception
.
Pikiran?
lib_foo_exception
kelas saya berasal std::exception
, pengguna perpustakaan akan menangkap lib_foo_exception
hanya dengan menangkap std::exception
, selain ketika ia hanya menangkap perpustakaan. Jadi saya juga bisa bertanya Haruskah perpustakaan saya pengecualian kelas root mewarisi dari std :: exception .
lib_foo_exception
?" Dengan mewarisi dari std::exception
Anda dapat melakukannya dengan catch(std::exception)
ATAU dengan catch(lib_foo_exception)
. Tanpa berasal dari std::exception
, Anda akan menangkapnya jika dan hanya jika , oleh catch(lib_foo_exception)
.
catch(...)
. Itu ada di sana karena bahasa tersebut memungkinkan untuk kasus yang Anda pertimbangkan (dan untuk perpustakaan "nakal"), tapi itu bukan praktik terbaik modern.
catch
, dan juga transaksi yang lebih kasar yang memodelkan operasi pengguna akhir. Jika Anda membandingkannya dengan bahasa yang tidak mempromosikan gagasan penangkapan secara umum std::exception&
, misalnya, mereka sering memiliki lebih banyak kode dengan try/catch
blok perantara yang berkaitan dengan kesalahan yang sangat spesifik, yang agak mengurangi generalisasi penanganan pengecualian karena mulai terjadi. penekanan yang jauh lebih kuat pada penanganan kesalahan manual, dan juga pada semua kesalahan berbeda yang mungkin terjadi.
std::exception
tidak berarti Anda membuang sebuahstd::exception
. Juga,std::runtime_error
apakah mewarisi daristd::exception
sejak awal, danwhat()
metode itu berasal daristd::exception
, bukanstd::runtime_error
. Dan Anda harus membuat kelas pengecualian sendiri alih-alih melemparkan pengecualian umum sepertistd::runtime_error
.