SolmyR's small piece series 7: abnormal

zhaozj2021-02-17  143

heavy rain.

The black cloud is like a low pressure, and the glass window of the bean is playing. It's rare abnormal weather that is trying to express it. However, all this does not seem to affect Solmyr. He still lying in a large chair with his habitual pose, holding a hot juice in his hand, behind him, Zero knocked on the keyboard.

"Hey, Solmyr, how will stack in the standard library look? The design is determined." Zero stopped working, turned around to face SolmyR, which looks a bit confusing.

"Members who are incorporated into the sacred standards will be sent to the people." SolmyR low-headed heads, and reputation with a desperate tone.

I don't know if God is going to strengthen Solmy 'persuasion. At this time, the sky has a lightning, the blue white electric light struggles work hard to rush to the ground, followed by "Kara" a loud noise --- This Lei is very close .

The Zero expression that I was thinking "this unwind to" was still thinking that "this is not too too much too much." He marked two lines of code to say: "Okay, ok, Solmyr, then explain why stack's interface is like this."

Std :: Stack Si; ... int i = si.top (); si.pop ();

"Just let POP () return to the top element of the top, and more intuitive, why do you want to make it now?"

We have witnessed the impulse of Zero expression, and the impulse is so laughing --- God knows how hardful - slowly put the cup in the table, turning around to tell this question:

"The reason is abnormal."

"abnormal?"

"Yes, many codes are very good at work when there is no abnormality, but once an abnormality becomes unpacking, it is like a hut, usually doesn't seem to have any problems, and I encountered this weather ...", SolmyR It refers to the finger window, "... it will be collapsed immediately. Consider how to implement if the POP () returns the top element, assumes that the stack is implemented with an array, and does not consider whether the stack is empty."

"It's very simple.", ZERO opened the editor and wrote:

Template T stack :: POP () {... ... Return Data [TOP -] // Assume that data is stored in array DATA, TOP represents the top position of the stack}

Solmyr shakes his head: "This is the Mao House. To know that Stack is a template class, it is stored in the element T may be a user-defined class. I will ask you, if the type T copy constructor throws an exception, what happens? "

"Well ..., return, return value is a temporary object, the temporary object is constructed in Data [TOP] ... Well, this will throw an exception when returning, and the customer cannot get this element at this time."

"anything else?"

"and also?"

"Tips, what is your TOP?"

"... Oops! Worse! TOP has been reduced, the top elements are lost! In this way ... must implement a function to allow customers to modify ...", Zero can't go. He thought for a while, shook his head to recognize the failure: "No, the copy structure is after the function returns, no matter how it is unable to avoid this. You can only write in the document: The copy constructor of the required T does not throw an exception. "Zero stopped, carefully asked Solmyr:" This is not too much demand? "SolmyR's answer is abnormal short:" new "

"Oh, New, New :: Bad_alloc ... I didn't say it. Solmyr, I understand that in order to deal with an abnormal situation, adjust the top position of the stack must be completed in all data copies, The value is returned is unacceptable. "

"Correct. So it is unacceptable for a standard library member for a design goal." SolmyR suddenly said: "And the influence of abnormality is far more than this. I Just said 'hypothesis the internal use of array in the stack', but if you take into account the various possibilities of the abnormality, you will find that the realization of the array is a bad idea. "

"... ... ... ...... ...... Why? Why do we always capture an exception in the event?", Zero is cautious.

Solmyr thumbs up looking at Zero. "Thinking it first before you ask, habits." SolmyR thought, but his face did not show: "Yes, but capture the exception does not mean you always handle it. Consider Stack's assignment operator If we use an array to implement, then there will be a loop similar to this when copying the data: "

// The meaning of each variable is the same Template Stack & Stack :: Operator = (Const Stack & r Hs) {... for (int i = 0; I

"Now considering the assignment operator of the type T may throw an exception, how to modify the above code." SolmyR stopped and raised the cup again.

"Use TRY ... oh ... ... ... ... ...... ...", Zero seems to find the problem, silent, and then said: "This loop may throw an abnormality when running to half. This will result in a part of the data has been successfully assigned, but the other is still old. Unless we use catch (...) to capture all exceptions, ignore it and continue to assign aid. "

"But this ...", SolmyR conscious guidance ZERO continues to think deeply.

"... But this, the exception thrown by the assignment is to eat, ', and the abnormality always represents some things that should not happen, so it should let customers receive this exception." ZERO Wrinkled with brows, a word, it is quite hard.

"Correct. Stock as a common standard library member, must do two points in the face of anomalies. First, unusual security, that is, the exception does not cause it to be in a wrong state or cause data loss or A resource leakage; two, abnormal transparency, that is, customer code - here means that it is stored in the type T implementation - throwing any exception, should not be eaten or changed, should be transparent Give the customer. I hope that the above code is unable to do this at the same time. "" Yes, I understand, this is probably the main reason why Stack in the standard library does not need to be realized. ", Zero showed very Have a grasp the look.

"Of course not! It's a bit common knowledge, if you implement the size of Stack, how can you accept it ?!"

Any time, Solmyr witnessed the dramatic changes in the occurrence of Zero expression. This time he didn't respond to the urge to laugh, even the juice in the cup also sprinkled out, a time, laughter is full of office - not just his, but also includes it (the public should be Guess it?) Onlookers' laughter.

After disconnecting the onlooker, Zero is sitting down: "Is there so funny?"

"Sorry, I am sorry, I ... hahaha ... I ... haha ​​... I just can't help ... Hahaha ...", Solmyr is so easy to laugh, sit straight, put the juice, positive color : "The key is that the two principles should be followed above, that is, unusual security, and abnormal transparency. Now you consider if the data inside the Stack is stored, how to ensure the above two points in the assignment operator?"

"... um ... still have the same cycle as the above ... Hey ...", there is a color color in Zero.

"Tips, don't have to copy directly to STACK Save Data Memory."

"... um ... not directly copy, then it is ... is copy to ... ah! I understand!", Zero seized the key, flying down:

/ / PDATA represents a pointer to the storage data memory, TOP represents the offset of the stack top element Template Stack & Stack :: Operator = (Const Stack & r Hs) {.. . ... T * PTEMP = New T [rhs.top]; try {for (int i = 0; i

Delete [] pdata; // Release the current memory PDATA = PTEMP; // Let PDATA point to the successful memory block ...}

"As long as this", Zero is input while saying, "Just copy the data to a temporary allocation buffer, and process an exception during this process, then let PDATA points to successfully assign the memory. The key is to let copy action Being able ... Uh ... can be safely canceled, the rest of the assignment is the simple pointer assignment, definitely not throwing an exception. "

"Very good. It is worth pointing out that this is a fairly common means. It is called Copy & Swap. It can not only be used to deal with an exception, and some other features can be effectively implemented. OK, this problem is probably Yes. "The problem seems to be able to tell a paragraph, Solmyr starts to intend to end this topic. The expression of Zero stopped him.

"Is there any problem? Zero?"

"Ah ... Nothing, I just thought, abnormal caused so much trouble, this time, there is a last thread deadlock problem (see the" small piece series "," pair ") is because Abnormal existence will become so complicated, what is the C still supports it? If there is a mistake, you can report it in return value. "

"Well, this is really a common doubt, but the answer is also very simple, there is an abnormal existence of its own value. First, use an exception report error can avoid the pollution function interface; Second, if you want to report a relatively rich error message, use An exception object is more effective than a simple return value, and avoids the overhead of returning complex objects; three, and I think it is more important, some errors are not suitable for returning value to report. For example, dynamic memory allocation. I Ask you, how to report dynamic memory distribution errors in the C language? ", SolmyR turned to look at Zero.

"The Malloc function returns a NULL value represents the dynamic memory allocation error."

"But how many C programmers have checked the return value after each time using Malloc?"

"..."

"Nothing? This is normal, check the return value after using Malloc, it is a painful thing, so even Steve Maguire (Note:" Writing Clean Code "book author of the author) This old program is teach Early, there is a code of tens of thousands of C procedures: ", SolmyR Type:

/ * Traditional C procedures * / int * p = malloc (sizeof (int)); * p = 10;

"Once Malloc fails to return null, this program will crash. However, if it is a C program, use new words ...", SolmyR typed the corresponding code:

// C program int * p = new int; * p = 10;

"There is no such problem. I ask you, why?"

Zero quickly found the answer: "Because if the New fails, it will throw the std :: bad_alloc exception, so the function is interrupted, exit, the following line will not be called."

"Correct. And you don't have to handle this exception every place, you only need to write your procedure to write the Try ... catch pair in the main function, capture all unpaged exceptions. For example you can Capture std :: bad_alloc in the main function, in output 'memory is' error message, then save all unsaved data, complete all cleanup work, finally end the program. When you say, the decent exit. "

Zero points, muttered repeated: "Yes, decent exit."

See ZERO to understand what he meant, Solmyr continues to start the next issue: "Existence of abnormal existence has the last important value --- is also one of the original intentions of the original design, providing a general means to make the constructor can be convenient Report error: Because the constructor does not return a value. "" "There is also a destructor." Without SolmyR, ZERO added this sentence.

SolmyR shook his head against self-high Zero: "Don't want to be of course, there is a very important principle about abnormal: Never let your destructive function throw an exception. Do you know why?"

"... I don't know." ZERO decided to recognize this time.

"Because the desctors that throw an abnormality can cause the easiest program to run correctly, such as the following two sentences:" This appearance is on the screen, it seems to seem to have no flawless two lines of code:

Evil P = New Evil [10]; delete [] P;

"It's not something wrong with it? Take a closer look, it will call 10 EviL class destructor, assume that the pace 5 EVIL class is thrown out, what will happen? Happening?"

Zero has been meditation, and the sight is staring at the screen. It looks like a program that is executing complex operations, and is the kind of no output. However, there is not long, ZERO has changed a expression. This expression is usually described as a bamboo: "I know Solmyr, in this case, delete [] faces two difficulties. Select one, do not catch this exception, let it Communicate to the caller, but in this way, DELETE [] is interrupted, the following 5 Evil objects will not be released, resulting in resource leakage; selecting the second is to capture this exception to prevent resource leakage, but such a This exception was eaten by delete [], violated the principle of 'for abnormal transparency'. So, no matter how it does, it is impossible to properly handle the destructive system to throw an abnormality. "

Solmyr thumbs up: "Very good. Next, your task is ..."

"I know I know, is it to organize these discussions as a document? I will do it."

Zero turned and started to bury his head. SolmyR recovered again to half-story comfort, holding his juice, and slightly some unexpected discovery ---

The weather is fine.

=====================================

This small piece of text has a lot of reference to the following two articles:

"Exception Handling: a false seircurity" by tom cargill

Exception-Safe Generic Containers By Herb Sutter

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

New Post(0)