You are on page 1of 14

c 

 

 V VVV V.

V MV Ô VV V V V V VVVVV  VVVV V V MV cV V VV VVV V VV  V  V MV a  V  VV   V VV  V V VVV  V  V VVVVVV  VV V V V V  V.

com/en-us/library/z3f89ch8(VS.V MV › V V VV V V V VV V VV  V V VVVV  V V  V MV › VVV VV VV VV VV   V VV V V  V MV › V V VVV VV VV V VVV  V VV    VV   V VV V  V V http://msdn.aspx ›    .microsoft.80).

      .

.

.

.

.

     .

      .

   MV è   MV › .

.

.

 .

.

      MV Œ    MV › .

.

.

  .

.

      MV ›       .

.

  MV Œ.

  MV ›   .

   .

 .

 .

 .

.

   MV ›    .

.

  .

        MV Ô     .

   .

    .

 MV Π     .

    Ô   .

    Ô   .

 .

     .

       .

   .

   .

›   .

          V V V V  .

V V u      .  M   ŒV V void* pointer_variable.

V V .

.

    .

                .

.

             .

   ›.

    .

         .

float* test. float f. then exf=&i. int* exf. V V   .V V Ú   V V int i.

.

   .

    .

.

  .

  .

  .

V V  .

.

V V .      V V exf=&f.

›      .

   .

.

.

› .

       .

   .

     .

   .

    .

.

 V V Œ.

   .

.

.

 .

   .

     .

 .

      .

V V ›       .  V V test=&i.

.

.

V V ›  .

 u       .

   .

.

.

        V V !     .

.

.

.

   .

    .

V V void* sample. V V !      "             .

      .

      .

.

 .

   .

.

 V V sample=&i. V V !            .

           .

      .

    .

    .

   .

.

 V V sample=&f. V .

V   .

   .

   .

      .

    .

          ›.

.

           .

  .

 V V ›   .

.

     .

 .

# .

.

        .

 › .

.

.

           .

    $.

.

    .

%.

 .

.

     .

  .

 ›.

.

.

      .

     .

  .

            .

   .

.

 ›  .

    .

   .

           $  &.

.

  $          .

'V V .

  ›   !((  .

 .

 .

        .

!((  .

      .

     .

     ).

›     .

    .

›     !((  .

        .

.

exforsys=0. V V ›          . V V Ú   V V int* exforsys.

      .

   .

                .

.

 ›       .

 !((  .

V V ›.

    .

!((  .

V V *u   .

      .

              !((   .

       .

               .

.

 .

  .

 .

       .

        !((   .

   .

  .

    .

        )V .

V Ú .

.

.

.

   .

.

 V V #include <iostream. } V V ›      .h> int *exforsys=NULL. void main() { *exforsys=100.

.

 V V NULL POINTER ASSIGNMENTV  › .

.

.

  .

 .

.

.

›       .

.

 .

      .

  .

 .

      .

 +     .

.

.

but are smarter.    è   Smart pointers are objects that look and feel like pointers. What does this mean? ›    .

 .

  .

    .

    .

      .

  .

 .

   .

.

 & .

 .

#'.

  & .

 .

'*            .$ .

    .

 .

 › .

  .

    .

 .

   %   .

  .

-.

  Π .

*.

  .

 ›  .

.

 .

 .

  .

 .

  .

      .

 .

  .

 /      0.  .

      Ô &Ô'.

.

     .

 .

      .

 .

    .

  .

 1  .

  .

 .

         .

 .

›    .

  .

  2 .

   .

Ô  .

.

3   .

4 .

 . .

   Π5 .

. 2 .

    1.

 .

  2 .

     ..

auto_ptr is a simple wrapper around a regular pointer. Its smartness in the destructor: the destructor takes care of deleting the pointer.} T* Ê () {return ptr. }. It forwards all meaningful operations to this pointer (dereferencing and indirection)...      template <class T> class Ê  { T* ptr. Ú . cs you can see. public: explicit Ê (T* p = 0) : ptr(p) {} Ê () {delete ptr.} // .} T& Ê() {return *ptr.

  .

  2 .

       .

   void „() { .

Ê* p(new .

Ê). delete p. } 2ou can write: void „() { Ê < . p->().

Ê> p(new .

/       0Œ      è  . } cnd trust p to cleanup after itself. p->(). Ê).

    übviously. è [  c   . Here are some common reasons for using smart pointers in C++. different smart pointers offer different reasons for use.

but in reducing the probability for bugs: you don't need to remember to free the pointer. . and so there is no chance you will forget about it. The importance here is not so much in the keystrokes saved. using smart pointers that clean after themselves can save a few lines of code. cs the code above illustrates.

c  .

  * .

  )  2 .       .

  !((     .

 .

     .

 ›       .

 .

.

.

  .

      *    .

 .

  .

      .

  .

           .

  ›     .

         .

Ê* p(new .

Ê). .

and have q point to this copy. ptr = rhs. MV ü     : Let both p and q point to the same object. This strategy is implemented in linked_ptr. This strategy is implemented in counted_ptr. this is solved by setting its pointer to NULL when it is copied: template <class T> Ê <T>& Ê <T>::Ê(Ê <T>& rhs) { if (this != &rhs) { delete ptr. Ê* q = p. } return *this. è a    . This strategy is implemented in cow_ptr. MV Õ     : The same as reference counting. where p and q are smart pointers: MV Ô     of the object pointed by p. rhs.ptr. MV Ô    : Use reference counting or linking as long as the pointed object is not modified.h. maintain a circular doubly linked list of all smart pointers that point to the same object. MV Õ     : Maintain a count of the smart pointers that point to the same object. This strategy is implemented in owned_ptr.// p is no longer dangling q->().h. p->(). The è  section of this article discusses the suitability of different smart pointers for various situations. Here are some possible strategies for handling the statement q = p. only instead of a count. delete p. Scott Meyers offers another reference counting implementation in his book More Effective C++. // Ouch! q is still dangling! Úor auto_ptr. Each has each own benefits and liabilities. // Watch out! p is now dangling! p = NULL.h. This strategy is implemented in copied_ptr. So the statement q = p causes the count of the object pointed by p to increase by one. cll these techniques help in the battle against dangling pointers.ptr = NULL. copy it and modify the copy. } üther smart pointers may do other things when they are copied. but transfer the responsibility for cleaning up ("ownership") from p to q.h. and delete the object when this count becomes zero. When it is about to be modified.h.

 Let's take another look at this simple example: .

void „() { .

Ê* p(new .

delete p. Ê). } What happens if DoSomething() throws an exception? cll the lines after it will not get executed and p will never get deleted! If we're lucky. threads. mutexes) and so not calling it my cause severe resource locks. transactions. this leads only to memory leaks. MyClass may free some other resources in its destructor (file handles.   . However. CüM references. p->().

  .

 .

.

         .

   .

   .

     .

.

       .

     6  .    .

      .

 .

  .

0Œ.

                .

  .

 1.

          void „() { .

Ê* p. try { p = new .

} } Now imagine what would happen if we had some if's and for's in there. delete p. è M.. Ê. p->(). } catch (. throw..) { delete p...

.

     Since C++ does not provide automatic garbage collection like some other languages. è a   Smart pointers can be used to make more efficient use of available memory and to shorten allocation and deallocation time. *   . but it is quite possible to implement more sophisticated garbage collection schemes with smart pointers. smart pointers can be used for that purpose. Úor more information see the garbage collection Úc . The simplest garbage collection scheme is reference counting or reference linking.

   .

   .

 .

      .

 &Ô-/'›          .

  Ô-/  .

        .

   / .

  .

.

 .

       &7.

 7' Ô-/  .

.

                   .

   › .

 .

          Ô-/   &  4 .

. .

' .

 s("Hello").// a new buffer is allocated for t before  // appending " there!". so s is unchanged. - )     .  t = s. // t and s point to the same buffer of characters t+= " there!".

                .

  .

  .

 Ú .

           ) .

       .

*          )        $   .

 .

 .

   .

   .

    .

     )  .

           .

       .

 .

          .

  .

  .

              .

  .

  è  [ .

<ÔÊ> v. Ê(new ÔÊ).. it cannot store of objects of classes derived from Base. Œ. v. v. STL containers store their objects by value. The problem with this solution is that after you're done with the container. i != v. class ÔÊ { /*. // OK v.(). ++i) delete *i. // OK too // cleanup: for (<ÔÊ*>::Ê i = v. // error What can you do if you need a collection of objects from different classes? The simplest solution is to have a collection of pointers: <ÔÊ*> v.(). Ê(b).*/ }. ÔÊ b..  The C++ standard library includes a set of containers and algorithms known as the standard template library (STL).. class  : public ÔÊ { /*. Ê(new ). STL is designed to be Y   (can be used with any kind of object) and   (does not incur time overhead compared to alternatives). This is both error prone and not exception safe. Ê(d)..  d. This means that if you have an STL container that stores objects of class Base. To achieve these two design goals. you need to manually cleanup the objects stored in it.*/ }. // OK v.

  .

.

      .

  &* .

      .

   .

     .

.' < <ÔÊ> > v.

 Ê(new ÔÊ). there is no need to manually delete the pointed objects. Ê(new ).  Œ›(  .v. // OK too // cleanup is automatic Since the smart pointer automatically cleans up after itself. // OK v.

     .

    & .

  .

 )   '›.

 .

     8  .

 .

         .

       ›      .

   .

   Œ›(  .

    .

 2 .

  .

$ .

 .

.

   .

Ú .

 .

       Ô 9.

< è    .  /:.

   cre you confused enough? Well. è  [ . this summary should help.

.

.

  The standard auto_ptr is the simplest smart pointer. If there are no special requirements. you should use it. well. standard. è  Ô. it is usually the right choice. and it is also. Úor local variables.

   clthough you can use auto_ptr as a class member (and save yourself the trouble of freeing objects in the destructor). class . as illustrated Below. copying one object to another will nullify the pointer.

. // .. Ê { Ê <int> p. }. .

// do some meaningful things with x . Ê x.

Ê y = x.      . // x.p now has a NULL pointer Using a copied pointer instead of auto_ptr solves this problem: the copied object (y) gets a new copy of the member.

.

   .

.

.

  .

        .

     =›.

 .

     .

     Ô-/  .

  .

.

  >  .

 è   [ .

   .  cs explained above. using garbage-collected pointers with STL containers lets you store objects from different classes in the same container.

    .

 .

 .

      .

       Π.

.

   >    .

.

.

.

 &              .

            .

     .

'    .

 .

            .

 .

 › .

  .

  .

  .

    .

           .

   .

.

 .

         9.

    .

.

     .

.

    .

  $  .

  .

                ›.

 .

     .

 .

.

    ?$.

.

      .

    .

3   .

.

 .

 ?$.

.

       $ .

  .

.

   .

8.

        .

    ›  2 .

    $ .

 .

.

just enough to store one or two more pointers. 6 . c reference linked pointer takes a little more space than a reference counted pointer . nor does it require any additional allocations.    Reference linking does not require any changes to be made to the pointed objects.

.

   .

.

 .

8.

       .

.

    .

   .

    è  a   .

e. you want to receive a pointer as a function argument. .   Sometimes. Taligent's Guide to Designing Programs recommends using "adopt" to mark that a function adopts ownership of a pointer. but keep the ownership of this pointer (i. üne way to do this is to use consistent naming- conventions for such cases. the control over its lifetime) to yourself.

!     .

    .

               .

    .

This way. The sharing is implemented using some garbage collection scheme. an object will be copied only when necessary. è      If you have objects that take a lot of space. like reference counting or linking. and shared otherwise. you can save some of this space by using CüW pointers. è   .

g. Ú    [   auto_ptr    Copied pointer [   Garbage collected pointer (e. reference counting/linking)       üwned pointer .

I recommend reading cndrei clexandrescu's chapter about smart pointers in his book Modern C++ Design. Úor a comprehensive and in depth analysis of the issues concerning smart pointers. they should be used with appropriate care.Y   Copy on write Ô    Smart pointers are useful tools for writing safe and efficient code in C++. Like any tool. Ú. thought and knowledge.

     .

  .

 .

  ›6 Ô .

.

   .

  .

.

 .

.

 .

        %  .

 .

  .

.

.

  .

 .

   .

è    Œ   .

&    77 .

7.

7  .

' Ô  .

 .

          Ô  .

      .

    .

     . !((   .

  .

.

  .

  .

                 è  .

   .

        .

.

 .

   .

@    ..

  .

            ›.

.

  ?        .

 '     '   .

 '  .

  .

  .

          .

.

       .

 .

     .

.

.

  ’ ’ › .

     .

   ’ ’   è   .

        .

       .

       .

 .

  .

7 .

7  .

    .

   ›.

 .

    .

  .

     &   .

 ' .

    .

.

.

  -  .

   .

    .

  Π      .

 .

   .

   .

.

  -.

 .

  .

.

       .

  .

&  .

 .

.

 .

 .

          .

7 .

7 ' è   .

         $ .

     .

     & .

.

.

 .

    '    .

    1 .

     .

   .

 .

     .

          .

   .

  .

  .

    .

  .

›.

    .

 .

     .

   .

 .

.

     .

        .

 .

     %  .

  .

    =A  .

    .

  .

  . .

   .

.

  .

        .

  .

   Π   7 .

.

 7- .

 .

 .

         .

           3  $ .

   .

  .

 .

  .

          .

  .

.

 *           .

    0                 Œ.

 .

  =Ô           7 .

 7   .

   .

D  .

  .

      ›   .

 .

          .

    !     #  .

  .

  #.

 .

     .

45 Ô .  5 Ô # # .

.

 .

   .

         .

 .

Œ.

  . -     9 Ô &'   › .

.

   =       .

$.

 .

.

.

 .

        .

   .

.

.

 $   )  .

 $  !((  .

 $     .

 $  .

 /  .

B$      .

    .

  .

.

      .

 .

  .

 1 .

          .

       $   .

  .

       .

  .

   .

  .

    .

.

&   .

7 .

7    .

.

'/      06   .

 .

     7.

  7      .

 .

 & 6  . '1 .

       .

$      .

 .

      .

             .

    .

 .

   .

.

     &  .

.

   .

         .

 '3 .

       .

    .

 .

C .

 .

.

 .

C .

 .

  ›.

.

       .

     .

 .

.

    1 .

   .

.     !   .

   *  .

45 Ô .  .

        .

                   A .

        .

.

 .

         .

 .

     .

     .

  " 3 .

   .

 .

.

 .

 7.

7       .

1 06             2Œ5* ›2› 2      .

=›  .

  .

  .

    .

  .

  .

&       .

       uÔ '  .