Furthermore - Talk about the constructor and abnormalities in C ++ and Object Pascal

zhaozj2021-02-16  51

Author: Nicrosoft (nicrosoft@sunistudio.com) 2001.9.15 personal home page: http: //www.sunistudio.com/nicrosoft/ East Documents: http: //www.sunistudio.com/asp/sunidoc.asp we know, The constructor of the class is not returned. If the constructor construct object fails, it is impossible to rely on the error code. So how do I identify the failure of the constructor in the program? The most "standard" method is to throw an exception. The constructor failed, which means that the structure of the object fails, then throws an exception, what is the "half-dead" object will handle? This is the topic of this article. In C , after the constructor throws an abnormality, the destructive function will not be called. This is reasonable because the object is not constructed. That is, if the constructor has made some operations such as allocating memory, opening files, etc., such a class requires a self-employed member to remember what actions have been done. In C , the classic solution is to use STL's standard auto_ptr, which has a introduction in every classic C book, I am here to say it here. Here, I want to introduce a "unconventional" way, and their thinking is to avoid throwing anomalies in the constructor. We can add init (); and uninit (); member functions are used to make the resource allocation work that is easy to generate errors, and all members will be set to NULL in the real constructor, and then call init (); Determine its return value (or capture the exception thrown), if init (); fail, you call uninit () in the constructor; and set a flag indicating that the construct fails. Uninit () in accordance with whether the member is released for resources for NULL.

The sample code is as follows: Class a {private: char * str; int failed; public: a (); ~ a (); int init (); int uninit (); int fixedd ();}; A: a () {Str = null; try {init (); failed = 0;} catch (...) {failed = 1; uninit ();}} a :: ~ a () {uninit ();} int A :: INIT () {str = new char [10]; str, "abcdefghi"); throw 10; returnit 1;} int A :: uninit () {if (! Str) {delete [] str; str = null PRINTF ("Free Resource / N"); return 1;} int A: failed () {Return Failed;} int main (int Argc, char * argv []) {a * a = new a; if ( A-> Failed ()) Printf ("failed / n"); Else Printf ("succeed / n"); delete a; getchar (); return 0;} You will find, in int a :: init () The code contains Throw 10 (generating an exception, analog error), the execution result is: Free Resource Failed Free Resource Although uninit (); is called twice, but due to uninit (); (! STR)), therefore do not have errors. And if there is no exception (remove int A :: init (), the executive result is: successited free resource and normal processes have no difference. In Object Pascal (Delphi / VCL), this problem is very simple, because the OP is different from C , and after Create, the compiler will automatically call the destructive DESTROY. And it will determine which resources are allocated, and automatic recycling is implemented.

转载请注明原文地址:https://www.9cbs.com/read-28228.html

New Post(0)