Menyelesaikan Bab 3 Penanganan Pengecualian dan Kesalahan, kutipan
Konstruktor dan Pengecualian
Topik ini sering disebutkan di komunitas C++, namun sepertinya belum ada yang memperhatikannya di komunitas Delphi. Mungkin karena karakteristik bahasanya, pemrogram Delphi tidak perlu khawatir tentang masalah ini. Namun menurut saya pemrogram Delphi juga harus memahami masalah ini dan mengetahui bahasa apa yang diberikan kepada kita agar mudah bagi kita untuk mengabaikannya. Seperti kata pepatah, “Ketika kamu dikelilingi keberkahan, kamu harus mengetahui keberkahan tersebut.” Kita tahu bahwa konstruktor suatu kelas tidak memiliki nilai balik. Jika konstruktor gagal membuat objek, mustahil untuk mengandalkan pengembalian kode kesalahan. Lantas, bagaimana cara mengidentifikasi kegagalan konstruktor dalam program? Metode paling "standar" adalah: memberikan pengecualian. Kegagalan konstruktor berarti konstruksi objek gagal. Jadi setelah pengecualian dilempar, bagaimana objek "setengah mati" ini akan ditangani? Di sini, menurut saya penting untuk memiliki pemahaman tentang bagaimana C++ menangani situasi ini sebelum membaca. Di C++, destruktor tidak dipanggil setelah konstruktor mengeluarkan pengecualian. Pendekatan ini beralasan karena saat ini objek tersebut belum selesai dibangun. Jika konstruktor telah melakukan beberapa operasi seperti mengalokasikan memori, membuka file, dll., maka kelas C++ perlu memiliki anggotanya sendiri untuk mengingat tindakan apa yang telah dilakukan. Tentu saja, hal ini sangat merepotkan bagi pelaksana kelas, sehingga umumnya pelaksana kelas C++ menghindari memberikan pengecualian pada konstruktor (Anda dapat menyediakan fungsi anggota seperti Init dan UnInit, yang diserahkan kepada konstruktor atau klien kelas yang mereka panggil untuk menanganinya). kegagalan inisialisasi). Solusi yang disediakan oleh setiap buku C++ klasik adalah dengan menggunakan smart pointer (kelas standar STL auto_ptr). Di Object Pascal, masalah ini menjadi sangat sederhana, dan pemrogram tidak perlu mengkhawatirkannya. Jika suatu kelas Object Pascal melontarkan eksepsi pada konstruktornya, maka kompiler akan secara otomatis memanggil destruktor kelas tersebut (karena destruktor tidak boleh di-overload, maka dijamin hanya ada satu destruktor, sehingga kompilator tidak akan kebingungan. . di antara beberapa destruktor). Objek anggota umumnya dihancurkan di destruktor, dan metode Free() memastikan bahwa destruktor tidak akan dipanggil pada objek nil (yaitu objek anggota yang belum dibuat). itu juga memastikan Keamanan. ketik MyClass = classPRivateFStr : PChar; // Penunjuk string publicconstructor Create();destructor Destroy();end;constructor MyClass.Create();beginFStr := StrAlloc(10); FStr, 'ABCDEFGHI');munculkan Pengecualian.Buat('kesalahan'); Melempar pengecualian, tanpa alasan, hahaend;destructor A.Destroy();beginStrDispose(FStr); // Melepaskan memori di destructor WriteLn('Free Resource');end;varObj : TMyClass;i : integer;begintryObj : = TMyClass.Create ();Obj.Gratis();WriteLn('Berhasil');kecualiObj := nil;WriteLn('Failed');end;Read(i); // Jeda layar untuk mengamati hasil akhir yang berjalan. Dalam kode ini, konstruktor memunculkan pengecualian, dan hasil eksekusinya adalah: Free ResourceFailed saat ini" Output Sumber Daya Gratis" dihasilkan oleh kompiler yang secara otomatis memanggil destruktor. Oleh karena itu, jika dokumentasi kelas atau penulis kelas memberi tahu Anda bahwa konstruktor kelas mungkin mengeluarkan pengecualian, ingatlah untuk membungkusnya dengan try...kecuali! Perbedaan cara C++ dan Object Pascal menangani pengecualian yang diberikan oleh konstruktor sebenarnya adalah perwujudan dari ide desain kedua bahasa tersebut. C++ menganut gaya C dan berfokus pada efisiensi. Semuanya diserahkan kepada programmer dan compiler tidak melakukan tindakan yang tidak perlu. Objek Pascal mewarisi gaya Pascal dan berfokus pada makna estetika program. Kompiler membantu pemrogram menyelesaikan pekerjaan yang kompleks.