Apa perbedaan antara std::runtime_error
dan std::exception
? Apa gunanya masing-masing? Mengapa mereka berbeda sejak awal?
sumber
Apa perbedaan antara std::runtime_error
dan std::exception
? Apa gunanya masing-masing? Mengapa mereka berbeda sejak awal?
std::exception
adalah kelas yang tujuannya hanya untuk melayani sebagai kelas dasar dalam hierarki pengecualian. Tidak memiliki kegunaan lain. Dengan kata lain, secara konseptual itu abstrak kelas (meskipun tidak didefinisikan sebagai kelas abstrak dalam makna C ++ dari istilah tersebut).
std::runtime_error
adalah kelas yang lebih khusus, turun dari std::exception
, yang dimaksudkan untuk dilemparkan jika terjadi berbagai kesalahan runtime . Ini memiliki tujuan ganda. Itu dapat dibuang dengan sendirinya, atau dapat berfungsi sebagai kelas dasar untuk berbagai jenis pengecualian runtime error yang lebih khusus, seperti std::range_error
, std::overflow_error
dll. Anda dapat menentukan kelas pengecualian Anda sendiri yang diturunkan std::runtime_error
, serta Anda dapat menentukan pengecualian Anda sendiri kelas turun dari std::exception
.
Sama seperti std::runtime_error
, pustaka standar berisi std::logic_error
, juga turun dari std::exception
.
Inti dari hierarki ini adalah memberi pengguna kesempatan untuk menggunakan kekuatan penuh mekanisme penanganan pengecualian C ++. Karena klausa 'catch' dapat menangkap pengecualian polimorfik, pengguna dapat menulis klausa 'catch' yang dapat menangkap tipe pengecualian dari subtree tertentu dari hierarki pengecualian. Misalnya, catch (std::runtime_error& e)
akan menangkap semua pengecualian dari std::runtime_error
subtree, membiarkan yang lain melewati (dan terbang lebih jauh ke tumpukan panggilan).
PS Merancang hierarki kelas pengecualian yang berguna (yang akan membiarkan Anda menangkap hanya tipe pengecualian yang Anda minati di setiap titik kode Anda) adalah tugas yang tidak sepele. Apa yang Anda lihat di pustaka C ++ standar adalah salah satu pendekatan yang mungkin, ditawarkan kepada Anda oleh penulis bahasa. Seperti yang Anda lihat, mereka memutuskan untuk membagi semua jenis pengecualian menjadi "kesalahan runtime" dan "kesalahan logika" dan membiarkan Anda melanjutkan dari sana dengan jenis pengecualian Anda sendiri. Tentu saja ada cara-cara alternatif untuk menyusun hierarki itu, yang mungkin lebih sesuai dalam desain Anda.
Pembaruan: Portabilitas Linux vs Windows
Seperti yang Loki Astari dan unixman83 catat dalam jawaban dan komentar mereka di bawah ini, konstruktor exception
kelas tidak mengambil argumen apa pun sesuai dengan standar C ++. Microsoft C ++ memiliki konstruktor yang mengambil argumen di exception
kelas, tetapi ini bukan standar. The runtime_error
kelas memiliki konstruktor taking argumen ( char*
) pada kedua platform, Windows dan Linux. Agar portabel, lebih baik digunakan runtime_error
.
(Dan ingat, hanya karena spesifikasi proyek Anda mengatakan kode Anda tidak harus berjalan di Linux, itu tidak berarti itu tidak harus dijalankan di Linux.)
std::exception
. Tentu, semuastd
benda melempar kelas turunannya, tetapi sama sekali tidak ada alasan untuk hanya melemparstd::exception
objek turunan.std::exception
harus dianggap (perhatikan yang dipertimbangkan) basis abstrak dari hierarki pengecualian standar. Ini karena tidak ada mekanisme untuk menyampaikan pesan tertentu (untuk melakukan ini Anda harus menurunkan dan mengkhususkanwhat()
). Tidak ada yang menghentikan Anda dari menggunakan std :: exception dan untuk aplikasi sederhana mungkin itu yang Anda butuhkan.std::runtime_error
di sisi lain memiliki konstruktor yang valid yang menerima string sebagai pesan. Ketikawhat()
disebut pointer char const dikembalikan bahwa menunjuk pada string C yang memiliki string yang sama seperti yang diteruskan ke konstruktor.sumber
std::exception(std::string)
. Sekarang saya menyadari bahwa saya harus membuangstd::runtime_error
jika saya ingin kode saya berfungsi di Linux (GCC).