It consists of six parts: scoped_ptr, scoped_array, shared_ptr, shared_array, weak_ptr, and intrusive_ptr.
Scoped_ptr is similar to STD: auto_ptr, but its ownership is more strict. Once obtained, it cannot be transferred.
1 Namespace Boost {
2 Template <typename T> Class Scoped_ptr: noncopyable {
3 Public :
4 Explicit Scoped_ptr (T * P = 0 );
5 ~ Scoped_ptr ();
6
7 Void Reset (T * P = 0 );
8
9 T & Operator *() Const ;
10 T * Operator -> () Const ;
11 T *Get () Const ;
12
13 Void Swap (scoped_ptr & B );
14 };
15
16 Template <typename T>
17 Void Swap (scoped_ptr <t> & A, scoped_ptr <t> & B );
18 }
Member Functions
Explicit scoped_ptr (T * p = 0)
Constructor stores a copy of P. Note that P must be allocated with operator new, or null. During construction, t is not required to be a complete type. It is useful when the pointer P calls the result of an allocation function instead of calling New directly: Because this type does not need to be complete, you only need a Forward Declaration of type T. This constructor will not throw an exception.
~ Scoped_ptr ()
Delete the object to which the Pointer Points. Type T must be a complete type when it is destroyed. If scoped_ptr does not save resources when it is parsed, it will do nothing. This destructor does not throw an exception.
Void reset (T * p = 0 );
Resetting a scoped_ptr is to delete the saved pointer. If it exists, re-save p. generally, the resource life management should be fully handled by scoped_ptr, but in rare cases, the resource needs to be released before scoped_ptr's analysis structure, or scoped_ptr needs to process another resource other than its original resource. In this case, you can use reset, but you must use it as little as possible. (Using it too much usually indicates a design problem.) This function does not throw an exception.
T & operator * () const;
This operator returns a reference to the object pointed to by the pointer stored in a smart pointer. Because null references are not allowed, resolving a scoped_ptr with a null pointer will lead to undefined behavior. If you are not sure whether the pointer is valid, use the get function to replace the unreference. This function does not throw an exception.
T * operator-> () const;
Returns the pointer saved by the smart pointer. If the pointer to be saved is null, calling this function will lead to undefined behavior. If you are not sure whether the pointer is null, you 'd better use the get function. This function does not throw an exception.
T * Get () const;
Returns the saved pointer. Be careful when using get because it can directly operate the bare pointer. However, get allows you to test whether the saved pointer is null. This function does not throw an exception. Get is usually used to call functions that require bare pointers.
Operator unspecified_bool_type () const
Returns whether scoped_ptr is not empty. The type of the returned value is unspecified, but this type can be used in the context (Boolean context) of Boolean. It is best to use this type conversion function in the IF statement, instead of using get to test the scoped_ptr validity.
Void swap (scoped_ptr & B)
Exchange two scoped_ptr contents. This function does not throw an exception.
Common functions
Template <typename T> void swap (scoped_ptr <t> & A, scoped_ptr <t> & B)
This function provides a better way to swap the content of two scoped pointer. It is better because swap (scoped1, scoped2) can be more widely used in many pointer types, including bare pointers and third-party smart pointers. Scoped1.swap (scoped2) can be used only for the smart pointer of its definition, but not for the bare pointer.
Usage
Scoped_ptrThe usage is no different from that of a common pointer. The biggest difference is that you do not have to remember to call delete on the pointer, and replication is not allowed.Typical pointer operations (operator * and operator->) are overloaded and provide the same syntax as bare pointers. The use of scoped_ptr is as fast as the use of bare pointers, and there is no increase in size, so they can be widely used. When boost: scoped_ptr is used, the header file is included."Boost/scoped_ptr.hpp"When a scoped_ptr is declared, the parameter of the class template is specified with the type of the theme. For example, the following is a scoped_ptr containing STD: String pointer:
Boost: scoped_ptr <STD: String> P (new STD: string ("hello "));
When scoped_ptr is destroyed, it calls delete on its pointer.
1 Int Main ()
2 {
3 Boost: scoped_ptr < String > Sp ( New String ( " Hello world! " ));
4 Cout <* sp <Endl;
5 Cout <SP-> size () <Endl;
6
7 * Sp = " Hekexin " ;
8 Cout <* sp <Endl;
9 Cout <SP-> size () <Endl;
10
11 // Resetting a scoped_ptr is to delete its saved pointer. If it has one,
12 // And re-save P. Normally, the resource lifetime management should be completely handled by scoped_ptr,
13 // However, in rare cases, resources need to be released before the scoped_ptr destructor, or scoped_ptr
14 // To process another resource other than its original resource. In this case, you can use reset, but do
15 // Use it less. (Using it too much usually indicates a design problem.) This function does not throw an exception.
16 Sp. Reset ();
17 Assert (sp. Get () = 0 );
18 Assert (sp =0 );
19 Assert (! SP );
20
21 Return 0 ;
22 }
Scoped_array: wraps new [] instead of new, providing a proxy for dynamic arrays. Consistent with scoped_ptr's design philosophy, it cannot be assigned a value, copied, and can only be used within the declared scope. The interface is also similar. features:
1. the pointer accepted by the constructor must be the result of new [] or 0.
2. There is no *-> overload operator, because it is not a common pointer.
3. The [] overload operator is provided, which is accessed using the following table like an ordinary array.
4. There are no container-like iterator operations such as begin () and end.
In fact, we should try to allocate less arrays dynamically and use vector instead.
IntMain ()
{
Boost: scoped_array <Int> SAP (New Int[100]);
STD: fill_n (& sap [0],100,5);
SAP [0] = Sap [2] + Sap [3];
For(IntI =0; I <100; ++ I)
{
Cout <sap [I] <Endl;
}
Return 0;
}
Shared_ptr is very useful. The introduction of reference counting allows it to assign values, copy and any share, or store it in a container.
1 Int Main ()
2 {
3 Shared_ptr < Int > Sp ( New Int ( 10 ));
4 Cout <* sp <Endl;
5 Assert (sp. Unique ());
6
7 Shared_ptr < Int > SP2 = sp;
8 Assert (sp = SP2 & sp. use_count () = 2 );
9 * Sp = 100 ;
10 Assert (! Sp. Unique ());
11 Cout <* SP2 <Endl;
12
13 Sp. Reset ();
14 Assert (! SP );
15 Cout <* SP2 <Endl;
16 Cout <sp2.use _ count () <Endl;
17
18 Return 0 ;
19 }
1 Class Shared
2 {
3 Private :
4 Shared_ptr < Int > SP _;
5
6 Public :
7 Shared (shared_ptr < Int > P): SP _ (p ){}
8 Void Print ()
9 {
10 Cout < " Use count: " <SP _. use_count () < " VAL: " <* SP _ <Endl;
11 }
12 Void Print_func (shared_ptr < Int > SP)
13 {
14 Cout < " Use count: " <Sp. use_count () < " VAL: " <* Sp <Endl;
15 }
16
17 Void Print_func1 (shared_ptr < Int > & SP)
18 {
19 Cout < " Use count: " <Sp. use_count () < " VAL: " <* Sp <Endl;
20 }
21 };
22
23 Int Main ()
24 {
25 Shared_ptr < Int > Sp ( New Int ( 100 ));
26 Shared S1 (SP );
27 Shared S2 (SP );
28 S1.print (); // 3,100
29 S2.print (); // 3,100
30
31 * Sp = 200 ;
32 S1.print (); // 3,200
33 S2.print (); // 3,200
34
35 S1.print _ FUNC (SP ); // 4,200
36
37 S1.print (); // 3,200
38
39 S1.print _ func1 (SP ); // 3,200
40
41 Return 0 ;
42 }
1 Int Main ()
2 {
3 Shared_ptr < String > Sp = make_shared < String > ( " Hello world! " );
4 Shared_ptr <vector < Int > SPV = make_shared <vector < Int > ( 10 , 3 );
5 Assert (* sp = " Hello world! " );
6 Assert (sp. Unique ());
7 Assert (SPV-> size () =10 );
8 Vector < Int > & VEC = * SPV;
9
10 Typedef vector <shared_ptr < Int >;
11 Vs spvec ( 10 );
12 Cout <spvec. Size () <Endl;
13 Int I =0 ;
14 For (Vs: iterator ite = spvec. Begin (); ite! = Spvec. End (); ++ ITE)
15 {
16 * Ite = make_shared (++ I );
17
18 }
19 Return 0 ;
20 }