C ++ programming Specification Library

Source: Internet
Author: User

8 standard library

The STL standard template library is used in different products to varying degrees. Some basic rules and suggestions are listed here for reference by various teams.

Rule 8.1 avoid using auto_ptr

Note: STD: auto_ptr In the STL library has an implicit ownership transfer behavior, as shown in the following code:

Auto_ptr <t> P1 (new t );
Auto_ptr <t> P2 = p1;
After the statement of Row 3 is executed, P1 no longer points to the object allocated in Row 3, but changes to null. Because of this, auto_ptr

Cannot be placed in various standard containers.

The transfer of ownership is generally not the expected result. For scenarios where ownership must be transferred, the implicit transfer method should not be used.
This usually requires the programmer to exercise extra caution on the code using auto_ptr, otherwise there will be access to the NULL pointer.

Auto_ptr is commonly used in two scenarios. One is to pass the auto_ptr function externally as a smart pointer, and the other is to use

As the raiI management class, auto_ptr Automatically releases resources when the lifecycle of auto_ptr is exceeded.

For 1st scenarios, you can use boost: shared_ptr or STD: tr1: shared_ptr (in the C ++ 11 standard

STD: shared_ptr.

For 2nd scenarios, use boost: scoped_ptr or STD: unique_ptr in the C ++ 11 standard. Where

STD: unique_ptr is a substitute for STD: auto_ptr and supports explicit ownership transfer.

Exceptions:

Before the C ++ 11 standard is widely used, STD: auto_ptr can be used to transfer ownership,

However, we recommend that you encapsulate STD: auto_ptr and disable the copy constructor and value assignment operator of the encapsulation class so that the encapsulation class cannot

Used for standard containers.

Rule 8.2 only uses scoped_ptr, shared_ptr, and unique_ptr to manage a single object

Boost: boost: scoped_ptr, boost: shared_ptr, STD: tr1: shared_ptr (in the C ++ 11 standard)

STD: shared_ptr) and STD: unique_ptr (C ++ 11 standard) are smart pointers used to manage a single object. When these SMART indicators

When the needle destroys the objects to which it points, it uses Delete instead of Delete [], and delete to delete the array is the undefined row.

Therefore, the preceding smart pointer management array cannot be used.

When you need an array with the raiI feature, you can use boost: scoped_array, boost: shared_array,

STD: vector <STD: tr1: shared_ptr> or STD: vector <STD: unique_ptr> (C ++ 11 standard.

Shared_ptr is a smart pointer based on the reference count and can be safely used in most scenarios. It requires a slight consumption when updating the reference count.

Some performance, in general, will not have a significant impact on the performance. Another issue that requires attention when using shared_ptr is not to generate

Generate cyclic references. A reference counting-based smart pointer may cause memory leakage when cyclic references occur. When loop reference is required

Use weak_ptr for a smart pointer.

Boost: shared_ptr, STD: tr1: shared_ptr (STD: shared_ptr) thread security and common types of STL thread 1

Cause:

1. Multiple Threads can read the same shared_ptr object at the same time;

2. Multiple Threads can write different shared_ptr objects at the same time.

Note: When multiple shared_ptr objects direct to the same underlying object, write these shared_ptr objects as thread security

All, but additional operations are required to ensure the thread security of the underlying object.

Rule 8.3 If circular references are involved, use weak_ptr to unbind the loop

Note: When shared_ptr based on reference count is used, the following circular references may occur, for example:

# Include <memory>
Class tchild;
Class tparent
{
Public:
Void setchild (STD: shared_ptr <tchild> const & Child)
{
Child _ = child;
}

PRIVATE:
STD: shared_ptr <tchild> Child _;
};

Class tchild
{
Public:
Void setparent (STD: shared_ptr <tparent> const & parent)
{
Parent _ = parent;
}

PRIVATE:
STD: shared_ptr <tparent> parent _;
};

Int main ()
{
STD: shared_ptr <tparent> parent = STD: make_shared <tparent> ();
STD: shared_ptr <tchild> child = STD: make_shared <tchild> ();

Parent-> setchild (child );
Child-> setparent (parent );

// Here, parent and child generate circular references. When parent and child are out of scope, memory leakage will occur.
}
To solve Memory leakage caused by loop reference, weak_ptr must be introduced. Modify the Code as follows:

Class tchild
{
Public:
Void setparent (STD: shared_ptr <tparent> const & parent)
{
Parent _ = parent;
}

Void useparent ()
{
// Get shared_ptr through lock () before using weak_ptr to point to the object.
STD: shared_ptr <tparent> parent = parent _. Lock ();
}

PRIVATE:
STD: weak_ptr <tparent> parent _;
};
Pay attention to the red part and the new useparent () function, which demonstrates how to use weak_ptr. Note that setparent ()

The parameter in the function is still shared_ptr, which hides the details of weak_ptr.

Shared_ptr. The example uses STD: shared_ptr in the C ++ 11 standard, but for Boost: shared_ptr and

STD: tr1: shared_ptr is also applicable.

Rule 8.4 uses make_shared instead of new to generate shared_ptr

Note: In the code, we can initialize shared_ptr in the form of STD: shared_ptr <t> A (New T. However

Using new in shared_ptr involves three potential risks.

First, the following code is prone to access the floating pointer:

T * A = new T;
STD: shared_ptr <t> B ();
A-> XXXXX; // when B-ultrasound is out of scope: the memory pointed to by a is released, and access error occurs.
Second, the following code is prone to duplicate delete:

T * A = new T;
STD: shared_ptr <t> B ();

// The following code appears again:
STD: shared_ptr <t> C ();
When a native pointer is used to initialize a shared_ptr, the reference count is set to 1, so two sets of independent reference counts appear,

When the reference count of the two groups reaches 0, the object will be destroyed, and the duplicate Delete problem will occur.

The third is the risk of Memory leakage. Consider the following code:

Int func1 ();
Void func2 (STD: shared_ptr <t> const & P1, int P2 );

Int main ()
{
Func2 (STD: shared_ptr <t> (New T), func1 ());
}
In the code that calls func2 above, the Code may be executed in the following order according to the compiler:

1. New T

2. func1 ()

3. STD: shared_ptr <t> Structure

In this case, if an exception is thrown in func1 (), a new T leak will occur. Therefore, we recommend that you use the new

Shared_ptr should be placed in a separate statement, and the code that calls func2 should be changed:

STD: shared_ptr <t> temp (new t );
Func2 (temp, func1 ());
The above method is a little cumbersome, and a variable is introduced. Make_shared with shared_ptr can be used

New initialization issues. In the preceding two cases, the code can be modified as follows:

STD: shared_ptr <t> B = STD: make_shared <t> ();
Func2 (STD: make_shared <t> (), func1 ());
The make_shared template constructs an object of the specified type and a shared_ptr and initializes shared_ptr with this object.

The task is completed in one step and there is no risk of exceptions thrown in the middle. For the type of parameters required during construction, add the parameters to make_shared

The template is enclosed in brackets.

Extended reading materials: Copyright tive C ++ Chinese Version 3 [us] Scott Meyers translated by Hou Jie 2006 published by the Electronics Industry

Article 17: Add a newed object to a smart pointer using an independent statement

Rule 8.5: Once shared_ptr is used for the same object, shared_ptr will be used everywhere.

Note: Rule 8.4 describes how to mix native pointers and shared_ptr to easily cause problems: Use of suspended pointers and repeated release. Therefore

The pointer of an object must be used in a unified manner, either using a native pointer or shared_ptr. Do not mix them.

Rule 8.6 derives from the enable_shared_from_this class for objects that return their own shared_ptr pointers

Note: For objects that require shared_ptr management, the corresponding shared_ptr must be used when the this pointer is required,

As can be seen from 3.4, if you directly use shared_ptr <t> (this) to construct a shared_ptr, it will cause a serious error. To this end,

Both boost and STL provide the corresponding enable_shared_from_this class, which provides a shared_from_this () function to return

Returns the shared_ptr corresponding to this pointer.

Example:

Class tclass: public STD: enable_shared_from_this <tclass>
{
Public:
STD: shared_ptr <tclass> getself ()
{
Return shared_from_this ();
}

STD: shared_ptr <tclass const> getself () const
{
Return shared_from_this ();
}
};

Rule 8.7 does not connect modules compiled using templates such as STL and boost of different versions.

(The template library uses a large number of inline functions. The modules compiled by different versions of the template library have fixed operations on the same data type .)

In this module. If the structure or memory layout of the same data type is different in the template library of different versions, it is defined in a module

When the object is operated by another module, a serious error may occur. Because static connection modules are often not divided into specific connections

Interfaces, which often access the objects defined in other modules.

Exceptions:

Some existing modules cannot obtain the source code, and it is impossible to re-compile the template library of the same version. In this case, for example

If the module defines clear interfaces and does not transmit risky Data Types in the interfaces, you can use them with caution.

Validation with sufficient rows.

Rule 8.8 does not save the string: c_str () pointer

Note: In the C ++ standard, the string: c_str () pointer is permanently valid. Therefore, the specific STL implementation can be fully called.

String: c_str () returns a temporary storage area and is quickly released. Therefore, to ensure program portability, do not save

String: c_str (), but is called directly whenever needed.

Example: // bad example:

STD: String demostr = "Demo ";
Const char * Buf = demostr. c_str ();
// The position indicated by BUF may be invalid.
Strncpy (info_buf, Buf, infobuf_size-1 );

We recommend that you do not pass the data types in the STL, boost, and other template libraries to the dynamic link library or other processes.

Note: There is another more complex problem in cross-dynamic link library or other processes. Generally, the memory allocation and release should be the same.

In a module, if the container or other data types are transferred to other modules for memory allocation and release by other modules,

It may cause unpredictable problems, usually program crashes or data disappears, but it may also be completely normal in some cases.

Therefore, it is difficult to locate the error.

We recommend that you evaluate whether a large number of inserted or deleted fragments will generate a large number of memory fragments when using the container 8.2.

Note: memory allocation policies vary for different operating systems and runtime libraries. Because most of the container memory is dynamically allocated

Repeated insertion and deletion operations may cause a large amount of memory fragments or memory unrecoverable.

For long-running service programs, we recommend that you evaluate and test whether the container will cause memory fragmentation when using containers.

At risk, you can use a memory pool (such as boost: pool) to avoid this problem.
We recommend that 8.3 use string instead of char *

Note: replacing char * With string has many advantages, such:

1. do not consider the ending '\ 0 ';

2. You can directly use the plus (+), minus (=), minus (=), and other string operation functions;

3. You do not need to consider the memory allocation operation, avoiding explicit new/delete and the resulting errors;

Note that in some STL implementations, the string is based on the write-time replication policy, which brings two problems. First, when writing some versions

The replication policy does not implement thread security. In a multi-threaded environment, program crashes. Second, when the replication policy is passed to the Dynamic Linked Library Based on the write policy

When copying the string of the policy, the pointer suspension may occur because the reference count cannot be reduced when the dynamic link library is detached. Therefore, be cautious

Selecting a reliable STL implementation is important to ensure program stability.

Exceptions:

When calling APIs of the system or other third-party libraries, only char * can be used for the defined interfaces *. However

You can use string before calling the interface, and use string: c_str () to obtain the character pointer.

When allocating character arrays on the stack as a buffer, you can directly define character arrays, do not use strings, and do not need to make

Use containers such as vector <char>.

We recommend that you use 8.4 containers provided by well-known template libraries such as STL and boost instead of implementing containers by yourself.

Note: well-known template libraries such as STL and boost have provided comprehensive functions. Instead of independently designing and maintaining an immature and unstable template library

Library, it is better to master and use the standard library. The use experience of the standard library already has mature experience and use skills in the industry.

We recommend that you use the new standard library header file 8.5.

Note: When STL is used, the header file uses <vector> and <cstring> instead of <vector. h> and <string. h>.

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.