C ++ Primer study note _ 90 _ tools for large programs -- Exception Handling [continued 3]

Source: Internet
Author: User

Tools for large programs -- Exception Handling [continued 3]

IX,Auto_ptrClass[Connect]

5. Copying and assigning auto_ptr objects are destructive operations.

Auto_ptrThere is a key difference between copying and assigning values with built-in pointers.. When copying an auto_ptr object or assigning its value to another auto_ptr object, transfer the ownership of the basic object from the original auto_ptr object to the copy object,OriginalAuto_ptrThe object is reset to the unbound status..

Auto_ptr
 
  
StrPtr1 (new string ("HELLO! "); Auto_ptr
  
   
StrPtr2 (strPtr1); cout <* strPtr2 <endl; cout <* strPtr1 <endl; // segment Error
  
 

After copying, strPtr1 no longer points to any object.

Unlike other copy or assign values, the copy and assign values of auto_ptr change the right operand. Therefore,The left and right operands of the value must be modifiable left values..


6. assign a value to delete the object pointed to by the Left operator.

In addition to transferring ownership from the right operand to the left operand, the assignment also deletes the object originally pointed to by the left operand-if two objects are different.

Auto_ptr
 
  
StrPtr1 (new string ("HELLO! "); Auto_ptr
  
   
StrPtr2; strPtr2 = strPtr1; cout <* strPtr2 <endl; cout <* strPtr1 <endl; // segment Error
  
 

Assign strPtr2 to strPtr1:

1) The strPtr1 object is deleted.

2) Set strPtr2 to the object referred to by strptr1.

3) strPtr1 is an unbound auto_ptr object.

[Careful mine]

BecauseCopying and assigning values are destructive operations.Therefore, auto_ptrs cannot store auto_ptr objects in standard containers. The container class of the standard library requires that two objects are equal after the copy or assignment. auto_ptr does not meet this requirement. If strPtr2 is assigned to strPtr1, strPtr1 is assigned after the assignment! = StrPtr2. replication is similar.



7. default constructor of auto_ptr

Auto_ptr
 
  
P_auto; // the object is not bound and does not point to any object.
 

By default, the internal pointer value of auto_ptr is set to 0. Unreferencing unbound auto_ptr objects has the same effect as unbinding pointer-what will happen if the program fails and is not defined:

    *p_auto = 1024;    cout << *p_auto << endl;    //Segmentation fault (core dumped)

8. Test the auto_ptr object

The test result is to determine whether the pointer is 0. However, you cannot directly test the auto_ptr object:

If (p_auto) // Error: the auto_ptr type is not defined to convert the types available as conditions * p_auto = 1024;

You must use its get Member:

If (p_auto.get () // returns the base pointer {* p_auto = 1024; cout <* p_auto <endl;} contained in the auto_ptr object ;} else {cout <"Unbound any object! "<Endl ;}


[Careful mine]

ShouldUse onlyGetInquiryAuto_ptrObjectOrUse the returned pointer Value, Cannot be usedGetCreate otherAuto_ptrObject.

Using get members to initialize other auto_ptr objects violates the auto_ptr class design principle: at any time, only one auto_ptrs object saves the given pointer. If two auto_ptrs objects Save the same pointer, the pointer is deleted twice.



9. reset operations

Another difference between the auto_ptr object and the built-in pointer is that you cannot directly assign an address (or another pointer) to the auto_ptr object:

    auto_ptr
 
   p_auto = new int(1024);   //Error
 

Instead, you must call the reset function to change the pointer:

    auto_ptr
 
   p_auto;    if (p_auto.get())    {        *p_auto = 1024;    }    else    {        p_auto.reset(new int(2048));    }    cout << *p_auto << endl;
 

To reset the auto_ptr object, you can pass 0 to the reset function.



[Careful mine]

When the reset function of the auto_ptr object is called, the object pointed to by the auto_ptr object (if any) will be deleted before the auto_ptr object is bound to another object ). However, just as the value assignment is ineffective, if the reset function of the same pointer already saved in the auto_ptr object is called, the object will not be deleted.



[Warning: auto_ptr defect]

To correctly use the auto_ptr class, you must adhere to the following restrictions imposed by this type:

1. do not use the auto_ptr object to save the pointer to the static allocation object. Otherwise, when the auto_ptr object itself is revoked, it will try to delete the pointer to the non-dynamic allocation object, leading to undefined behavior.

2. Never use two auto_ptrs objects to point to the same object. One obvious cause of this error is to use the same pointer to initialize or reset two different auto_ptr objects. Another subtle way to cause this error may be,Use oneAuto_ptrObjectGetFunction result to initialize orResetAnotherAuto_ptrObject.

3. Do not use the auto_ptr object to save the pointer pointing to the dynamically allocated array. When an auto_ptr object is deleted, it only releases one object-it uses the common delete operator instead of the delete [] operator of the array.

4. Do not store auto_ptr objects in containers. The container requires that the stored types define the copy and value assignment operators so that they are similar to built-in type operators: After copying (or assigning values), the two objects must have the same value, the auto_ptr class does not meet this requirement..



10. exception description

Exception Description: specifies that if a function throws an exception, the thrown exception will be included in this description, or a type derived from the listed exception.



1. Definition exception description:

Exception description follows the function parameter table. An exception indicates a list of exception types enclosed by parentheses following the keyword throw (which may be null:

void recoup(int) throw (runtime_error);

Note: If a recoup throws an exception, the exception will be of the runtime_error or runtime_error-derived type.

The empty description list indicates that the function does not throw any exception:

void no_problem() throw ();

Exception description is part of the function interface. The function definition and any declaration of the function must have the same exception description.

If no exception is specified in a function declaration, the function can throw any type of exception.



2. violation exception description

OnlyRuntimeTo detect whether a function exception is violated.

If the function throws an exception not listed in the exception descriptionCall standard library functionsUnexpected. By default, the unexpected function calls the terminate function, which usually terminates the program.

[Careful mine]

During compilation, the compiler cannot and will not try to verify the exception description.


Even if the function code is accidentally read and specified, it may throw exceptions not found in the exception description, and the compiler will not prompt:

// No error description is provided! Void f () throw () {throw exception ();}

Instead, the compiler generates code to ensure:If an exception violates the exception description,CallUnexpectedFunction.



3. Make sure the function does not throw an exception.

[Best practices]

An exception is useful in the following important cases: if a function can ensure that no exception is thrown.

Determining that a function will not throw any exceptions is helpful to both the function user and the compiler:

1) knowing that a function does not throw an exception will simplify the compilation of exceptional and secure code that calls the function. We can know that you do not have to worry about exceptions when calling the function,

2) If the compiler knows that it will not throw an exception, it can execute the optimization restricted by the code that may throw an exception.



4. exception description and member functions

Like non-member functions,The exception description of the member function declaration follows the function parameter table..

Class bad_alloc: public exception {public: bad_alloc () throw (); bad_alloc (const bad_alloc &) throw (); bad_alloc & operator = (const bad_alloc &) throw (); virtual ~ Bad_alloc () throw (); // The exception description is placed after the const qualifier virtual const char * what () const throw ();};


5. exception description and destructor

The isbn_mismatch class defines the Destructor:

class isbn_mismatch : public std::logic_error{public:    virtual ~isbn_mismatch() throw()    {    }};

The isbn_mismatch class is inherited from the logic_error class. logic_error is a standard exception class. The destructor of this Standard exception class contains null throw (), and they promise not to throw any exceptions. When inheriting one of these two classes, our destructor must also promise not to throw any exceptions.

class isbn_mismatch : public std::logic_error{public:    virtual ~isbn_mismatch();//Error};

The out_of_stock class has no members, so its constructor does not do anything that may throw exceptions. Therefore,The compiler can understand that the compositing destructor willObserve the promise of not throwing exceptions.

The isbn_mismatch class has two string class members, which means that the synthesis destructor of isbn_mismatch calls the string destructor. The C ++ standard ensures that string destructor do not throw an exception like any other standard library class destructor. However, the destructor in the standard library do not have an exception description,In this case,We know,HoweverThe compiler does not know, String destructor will not throw an exception. We must define our own destructor to restore the promise of no exception thrown by the destructor.



6. exception description and virtual functions

The exception description of the virtual function in the base class, which can be different from the exception description of the corresponding virtual function in the derived class.

However, the exception description of the derived-type virtual function must be the same as that of the corresponding BASIC-type virtual function, or be more restrictive than the latter.

This restriction ensures thatWhen you call a virtual function of a derived class to a pointer of the base class type, Exception description of the derived classNo new exceptions can be thrown.:

Class Base {public: virtual double f1 (double) throw (); virtual int f2 (int) throw (std: logic_error); virtual std: string f3 () throw (std: logic_error, std: runtime_error) ;}; class Derived: public Base {public: // The Derived class cannot add an exception double f1 (double) to the exception descriptor list) throw (std: underflow_error); // Error int f2 (int) throw (std: logic_error); // OK std: string f3 () throw (); // OK };

If you call a function through a base class pointer or referenceOnly the exception specified in the base class. The exceptions thrown by a derived class are limited to those listed by the base class. When writing code, you can know which exceptions must be handled. The Code may depend on the fact that:The exception list in the base class is the superset of the exception list that can be thrown by the derived class version of the virtual function.. For example, when calling f3, we know that we only need to handle logic_error or runtime_error:

void compute(Base *pd) throw(){    try    {        pd -> f3();    }    catch (const logic_error &le)    {        //...    }    catch (const runtime_error &re)    {        //...    }}

When determining what exceptions may need to be captured, the compute function uses the exception description in the base class.



11. function pointer exceptions

Exception description is part of the function type. In this way, the exception description can also be provided in the definition of the function pointer:

Void (* pf) (int) throw (runtime_error); // This function can only throw a runtime_error exception


If no exception is provided, the pointer canPoint to a function with a matching type that can throw any type of exception.

InUse another pointer to initialize a pointer to a function with an exception description., Or when the latter is assigned to the function address, the two pointers do not have to be the same exception. However,The exception of the source pointer must be at least as strict as that of the target pointer..

Void recoup (int) throw (runtime_error); void (* pf1) (int) throw (runtime_error) = recoup; // OKvoid (* pf2) (int) throw (runtime_error, logic_error) = recoup; // OK // The exception type thrown by the recoup function exceeds the value specified by pf3. Therefore, a compilation error is thrown. // However, Some compilers do not report an error here, for example, g ++! Void (* pf3) (int) throw () = recoup; // Errorvoid (* pf4) (int) = recoup; // OK

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.