Furthermore - Talk about the constructor and abnormalities in C and Object Pascal
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 that 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, such as the operation of opening files, such as their own members have 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]; strcpy (str, "abcdefghi"); throw 10;
Return 1;}
INT A :: uninit () {if (! str) {delete [] str; str = null;}
Printf ("free resource / n"); returnif 1;}
Int a :: failed () {returnified;
INT Main (int Argc, char * argv []) {a * a = new a; if (A-> Failed ()) Printf ("failed / n"); Else Printf ("succeeded / n");
Delete a;
GetChar (); Return 0;
You will find that in int A :: init () contains Throw 10; generating an exception, an analog error occurred), the execution result is: Free Resource Faled Free Resource Although uninit (); called twice However, due to uninit (); if it is determined (if (! Str)), there is no error. 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. Therefore, its code has also become very simple, as follows: Type a = Class Private str: pchar; public constructor create (); destiotor destroy (); override;
Constructor a.create (); begin str: = stralloc (10); strcopy (str, 'abcdefghi'); raise exception.create ('error'); end;
DeStructor a.destroy (); Begin Strdispose (STR); Writeln ('Free Resource'); END;
Var OA: A; I: INTEGER; begin try oa: = a.create (); writeln ('succeeded'); OA.Free (); Except OA: = NIL; Writeln ('failed');
READ (I); end.
In this code, if the constructor throws an exception (ie Create contains raise exception.create ('error'); the result of the execution is: Free resource failed This time "free resource" output is automatically made by the compiler Call the destructor generated. If the constructor is returned (ie, no exception), the execution result is: "Free Resource" output at this time is generated by OA.Free ().
In summary, C and Object Pascal have a different way of processing after constructor throwing abnormalities, in fact, it is a reflection of the design ideas of the two languages. C adheres to the style of C, paying attention to efficiency, all handed over to programmers to master, the compiler does not do extra action. Object Pascal inherits the style of Pascal, pay attention to the aesthetic meaning of the program (it is undeniable, the Pascal code is the world's best code), and the compiler helps programmers to complete complex work. There is a reason for the existence of two languages! And the difference between them can make you better control them and achieve the ideal kingdom of freedom.