[note]Effective C++ Chapter 3

6331 ワード

Effective C++ Learning Note 3 (undergradute edition)
Resource Management
===========================================
Use obj and smart ptrs
objects preform well in resource managing
Encapsulation is one of the most characteristics of OO-system. By using obj, we can betterly manage the resourses, for:
  • returing resources we’ve applied
  • guarantee the safety of our infos.

  • they can all be dealt (quite well) with by dtors.
    To tackle tricky Pointers
    When dealing with pointers, the strategies we stated before faced its stocks:
  • if there is a branch directly returns
  • (if delete in a loop, and we goto or continue halfway.)

  • if we wanna return an obj* ?(it’s quite troublesome) warning: this case is unnecessary, 'cause if we delete the new ed ptr, we delete the data on the address.
    Luckily, we have auto_ptr s and shared_ptr s defined in header file memory
    void f()
    {
    std::auto_ptr<Investment> pInv(createInvestment()); // call factory function
    ... // use pInv as before Page
    } //automatically delete pInv via auto_ptr's dtor
    

    This simple example demonstrates the two critical aspects of using objects to manage resources:
  • Resources are acquired and immediately(RAII, Resource Acquisition Is Initialization) turned over to resource-managing objects.
  • Resource-managing objects use their destructors to ensure that resources are released.

  • more on auto_ptr s and shared_ptr s
    To prevent that pointers to one obj were deleted repeatedly (causing undefine errors), auto_ptr s have an unusual characteristic: copying them (via copy constructor or copy assignment operator) sets copyee to null, and the copying pointer assumes sole ownership of the resource!
    the technique is compatible with the normal copying rules. (it possibly means that the normal copying didn’t erase the former units, while auto_ptr )
    to solve this problem, we have a technique named shared_ptr , during copying, it just add the cnt of ptr to an obj, when none is then pointed to the obj, it was deleted.
    sum-up
    To prevent resource leaks, use RAII objects that acquire resources in their constructors and release them in their destructors.(this is quite a general rules)
    copying in resource-managing class
    RAII obj sometimes should be prohibited to copy:
  • uncopyable technique(in item 6)
  • reference-count

  • sometimes, however, (if I like hhh) if RAII be copied,
  • the resources it manages shall be copied altogether(it means deep-copy)
  • else in some rare cases we need to use technique (transfer ownership of the underlying resource) like we do in auto_ptr

  • offer users access to raw resource.
    new and delete: in same form or not in vector
    e.g
    std::string *stringArray = new std::string[100];
    ...
    delete stringArray;
    

    if simply by the form of deleting one unit, the delete won’t know how many actions to excute.
    in this possible version:
    delete []stringArray;
    

    we can view it as a linear structure that started with a unit indicating the size of the array. if there is no [] , it’s likely to omit some not released.
    another solution is to use the containers in STL.
    using typedef is troublesome, for it seemingly needn’t []
    typedef std::string AddressLines[4]; // a person's address has 4 lines, 
                    // each of which is a string
    std::string *pal = new AddressLines;
    delete pal; // undefined!
    delete [] pal; // fine
    

    however, containers in STL are able to satisfy the needs (which motivates us to use typedef )