Chapter 12 and 13 of the C++primer

Source: Internet
Author: User

12th Dynamic Memory 12.1 Smart pointers

Shared_ptr<t>

Make_shared<t> (args)

Initializes the new int (10) directly;

Default initialization of new int;

Value initializes the new int ();

Dynamic presence that is managed by a built-in pointer (rather than a smart pointer) is displayed until it is released.

It is best to stick with smart pointers only;

Reset pointer value after delete is nullptr;

Unique_ptr

u = nullptr release U point to Object, set U to null

U.release () u discard control of pointer, return pointer, set U to null

U.reset () Releases the object to which U points

U.reset (q) Releases the object that U points to, and if Q is a built-in pointer, point u to this object

U.reset (nullptr) frees the object you are pointing to, and you are set to NULL

Example:

UNIQUE_PTR<STRING>P1 (New string ("STA"));

UNIQUE_PTR<STRING>P3 (New string ("Test"));

The pointer returned by release is often used to initialize another smart pointer or assign a value to another smart pointer.

P2.reset (P3.release ());

or unique_ptr<string> P2 (p1.release ());

12.2 Dynamic arrays

int *pia = new INT[10] (); 10 values initialized to 0 int

Delete [] PIA;

Smart pointers and dynamic arrays

Unique_ptr<int []> up (new int[10]); Up points to an array containing 10 uninitialized int

Up.release (); Self-use delete[] destroy its pointer

Allocator class

Allocator<t> A

A.allocate (N)

A.deallocate (P,n)

A.construct (P,args)

A.destroy (P)

13th Copy Control 13.1 Copy, assignment and destruction

When defining any C + + class, the copy control operation is a necessary part.

Copy construction and move constructs define what to do when the object is initialized with another object of the same type.

Copy assignment and move assignment define what to do when an object is assigned to another object.

String sbook = "C++primer"; Copy initialization

String B; Default initialization

b = Sbook; Copy Assignment

13.1.1 Copy Constructors

copy constructor: If the first parameter of a constructor is a reference to its own class type, and any additional arguments have default values , this constructor is a copy constructor.

Synthetic Copy constructors: If no copy constructor is defined, the compiler defines one for us.

In general, the synthesized copy constructor copies the members of the parameter individually to the object being created.

The type of each member determines how it is copied. Numeric members are copied individually.

Copy Initialization VS Direct Initialization

Reference: https://www.cnblogs.com/cposture/p/4925736.html

Direct initialization: Requires the compiler to use normal function matching to select the most matching constructor.

Copy initialization: Requires the compiler to copy the right operand to the object being created, and to convert the row type if necessary.

When does copy initialization occur?

1. ********* experiment when defining variables with =, temporary variables

2. Passing an object as an argument to a parameter of a non-reference type

3. Object returned from a function that returns a type of non-reference type ****** experiment, compiler optimization

4. Initialize an element in an array or a member of an aggregation class with a list of curly braces

5. Standard Container library Call insert or PUSH Member ********* experiment, Emplace is more efficient than push

Classtest ct2 = "AB"; Replication initialization actual ... The idea of the compiler is to use temporary variables without temporary variables.

Classtest CT6 = GetOne ();//Copy initialization actual ... The address of the CT6 directly into the function is initialized by line.

#include <map>

#include <iostream>

#include <unordered_map>

#include <vector>

#include <cstring>

Using Std::cout;

Using Std::endl;

struct T_test

{

unsigned int mme = 13;

int test = 5;

T_test () = default;

T_test (unsigned int _mme, int t)

{

Mme = _mme;

Test = t;

};

};

typedef struct VITERBINODE

{

int attr = 2;

}t_viterbinode;

unsigned char ip[] = "111.111.111.111";

struct T_CONSTRUCT

{

int a = 1;

int b = 2;

T_construct ()

{

std::cout<< "Default Construct" <<std::endl;

};

t_construct (int _a, int _b)

{

A = _a;

b = _b;

std::cout<< "param construct" <<std::endl;

};

T_construct (const t_construct& Other)

{

A = OTHER.A;

b = other.b;

std::cout<< "Copy Construct" <<std::endl;

};

};

Class Classtest

{

Public

Classtest ()

{

C[0] = ' + ';

cout<< "Classtest ()" <<endl;

}

classtest& operator= (const classtest &CT)

{

strcpy (c, ct.c);

cout<< "classtest& operator= (const classtest &ct)" <<endl;

return *this;

}

Classtest (const char *PC)

{

strcpy (c, PC);

cout<< "classtest (const char *pc)" <<endl;

}

Private

Classtest (const classtest& CT)

{

strcpy (c, ct.c);

cout<< "classtest (const classtest& CT)" <<endl;

}

Private

Char c[256];

};

Classtest GetOne ()

{

cout<< "GetOne begine" <<endl;

Classtest A ("a");

cout<< "GetOne End" <<endl;

return A;

};

int main ()

{

Std::vector<t_construct> v1;

Std::vector<t_construct> v2;

std::cout<< "Push:" <<std::endl;

V1.push_back (t_construct (3,4));

std::cout<< "Emplace:" <<std::endl;

V2.emplace_back (5,6);

cout<< "Ct1:";

Classtest ct1 ("AB");//Direct initialization

cout<< "CT2:";

Classtest ct2 = "AB";//Copy initialization

cout<< "CT3:";

Classtest ct3 = ct1;//Copy Initialization

cout<< "Ct4:";

Classtest Ct4 (CT1);//Direct initialization

cout<< "CT5:";

Classtest ct5 = Classtest ();//Copy initialization

cout<< "CT6:";

Classtest CT6 = GetOne ();//Copy initialization

}

Extension: Aggregation class

Meet the conditions:

All members are public

No constructors are defined

There is no initial value in the class, if there is an initial value, it cannot be assigned with {}, otherwise the compilation

There is no base class, and there is no virtual function

Insufficient:

All members Public

Give the user the right initialization work

After adding or removing a member, all initialization statements need to be updated

Initialization

Initializes the list, if the number is less than the number of members, the latter member is initialized by the value.

Default initialization:

If a variable of a built-in type is not displayed initialized, its value is determined by the location defined.

variables defined outside of any function body are initialized to 0 ;

Type variables that are defined inside the function will not be initialized.

Why is there such a difference?

1. Where the variable is stored;

2. C + + to be compatible with C.

POD class: one of the aggregation classes

Reference: https://www.cnblogs.com/DswCnblog/p/6371071.html

The definition of pod: a minimalist, standard layout

KW check: Non-pod class, can not use memset and other memory-like copy

memset (pthandleinfo, 0, sizeof (t_handleinfo));

Why do I need pods type?

You can use byte assignments, such as memset,memcpy operations

Compatible with C memory layouts.

This ensures that static initialization is safe and effective.

whether it is pod type?

C++11 use Std::is_pod<t>::value to judge

13.1.2 Copy assignment operator

foo& operator= (const foo&);

Understanding: The difference between copy initialization and assignment operators

string s = String ("2017"); S copy Initialization

String j,k;

j = k; Copy assignment operator using string

Experiment: Modify the Copy assignment operator to copy assignment or construct a number of times?

cout<< "***********a=getother (c)" <<endl;

D = Getother (c);

cout<< "***********getother (c)" <<endl;

Getother (c);

cout<< "*********t_construct e = Getother (c)" <<endl;

Const T_construct e = Getother (c);

13.1.3 Destruction function

A smart pointer is a class type and has a destructor. Smart pointer members are automatically destroyed during the destructor phase. Implicitly destroying a built-in pointer-type member does not delete the object it points to.

When do I call destructors?

1. Variables in the left scope are

2. When an object is destroyed

3. When the container is destroyed, its elements are destroyed

4. When a dynamic object is applied to delete

5. Temporary object when the complete expression that created it ends

The destructor body itself does not destroy members directly. A member is destroyed in the destructor phase that is suppressed after the destructor body.

Experiment:

cout<< "***********getother (c)" <<endl;

Getother (c);

Copy construct

Before return

Copy construct

Delete

Delete

13.1.435 Rule

1 classes that require destructors also require copy and assignment operations

2 classes that require copy operations also require assignment operations, and vice versa

13.1.5 using =default

The version that is displayed requires the compiler to generate the composition.

13.1.6 Block Copy

by =delete

In essence, when a member of a class cannot be copied, assigned, or destroyed, the composition copy control member of the class is defined as deleted.

Synthetic copy control members may be deleted:

If a class has data members that cannot be constructed, copied, copied, or destroyed by default, the corresponding member function is defined as deleted.

through private Copy Control (new standard, not recommended now)

Copy control members are declared as Pirvate, but they are not defined.

13.2 Copy Control and resource management

Two strategies:

1. class behaves like value, controlled by constructor and assignment function;

Class value Copy assignment operator: The assignment operator typically combines the operations of destructors and constructors .

Like destructors, assignment operations destroy resources on the left side of the object;

Like a copy constructor, the assignment operation copies data from the right operand;

2. the behavior of the class like a pointer, through the shared_ptr solution or reference calculation control;

How the reference count works:

The constructor also needs to create a reference count to record how many objects share state with the object being created, and when we create an object, only one object is shared, and the counter initializes 1

The copy constructor does not allocate a new counter, but instead copies the data members of the given object, including the counter. The copy constructor increments the counter, indicating that the state of the given object is also a new user.

The destructor decrements the counter, and if the counter becomes 0, the destructor frees the state.

The Copy assignment operator increments the counter of the right operand and then decrements the counter of the left operand. If the counter of the left operand becomes 0, the state is destroyed.

Assignment operators:

When assigning an object to itself, the assignment must be correct;

A good way to do this is to copy the right operand before destroying the left operand resource.

13.3 Swap Operation Swap

For classes that have allocated resources, defining swap can be an important optimization tool. (The exchange may be just a pointer to a member)

Class hasptr{

friend void swap (hasptr&, hasptr&);

};

Inline

void swap (Hasptr &lhs, hasptr &rhs)

{

Using Std::swap;

Swap (lhs.ps, rhs.ps);

}

13.4 Copy Control Example 13.5 dynamic memory management class

A good code example

Experiment: Vecoter capacity expansion and how copy p317vector objects grow?

       std::vector<t_construct> v1;

    std::vector<t_construct> v2;

       std::cout<< "Push 1:" <<STD::ENDL;

       v1.push_back (t_construct (3,4));

 

       std::cout<< "Push 2:" <<STD::ENDL;

       V1.push_back (t_construct (2,3));

      

       std::cout<< "emplace:" <<STD::ENDL;

       V2.emplace_back (5,6);

 

 

Push 1:

Param construct

Copy construct

Delete

 

Push 2:

Param construct

Copy construct

Copy construct

Delete

Delete

 

Emplace:

Param construct

How do I improve performance?

1, direct push_back () changed to use Emplace_back ();

2, reserve (n) predetermined n space, of course, subsequent push_back () will increase, where the value is not determined;

3, resize (n, x) request n space to initialize to X.

The reserve only maintains a minimum space size, while the resize is re-allocating the buffer,

It involves more judgment and more memory processing, so it's slower than reserve.

when the number of data can be determined, it is necessary to preset the space size first. Direct Push_back data is time-consuming to move frequently

c++11 improvements in space-time performance: Https://www.cnblogs.com/me115/p/4788322.html#h26

Size Fixed container array

Forward List Forward_list

hash Table [ unordered container] unordered containers

Constant-expression constexpr

Static Assertion Static_assert

Move semantic and rvalue references

In situ operation Emplace operations

13.6 Object Movement

Moving rather than copying objects can significantly improve performance.

The standard Reservoir, string, and shared_ptr classes support both mobile and copy support. The IO class and the Unique_ptr class can be moved but not copied.

13.6.1 rvalue Reference

An rvalue reference is an important property: it can only be bound to an object that will be destroyed.

Therefore: the referenced object will be destroyed;

There are no other users for this object.

What are the generated right values?

Returns a function of a non-reference type

Arithmetic, relationship, bit, post increment decrement operator

Std::move Standard library Move function: Shows the conversion of an lvalue to the corresponding rvalue reference type.

Note: in addition to assigning or destroying the source object, we will no longer use it.

After calling move, we cannot make any assumptions about the value of the source object after it is moved.

13.6.2 move constructor and move assignment operator

To allow our own type to support the move operation, you need to define the move constructor and the move assignment operator for it.

Move constructor

Strvector::strvec (Strvec &&s) noexcept//Must be noexcept

: Elements (S.elements)

{

S.elements = nullptr;

}

After moving, the source object should be secure. Destruction is harmless.

Move Assignment function

Strvec &strvec::operator= (Strvec &&rhs) noexcept

{

if (This! = &RHS)

{

Free (); Releasing an existing element

elements = rhs.elements;

Rhs.elements = nullptr; Source object can be destructor

}

return *this;

}

After a move operation, the source object must remain in a valid, reconfigurable state after it is moved, but the user cannot make any assumptions about its value.

why noexcept? ?

Vector exception handling protection.

Synthetic Move Operations : only if a class does not define any copy control members of its own version, and all its data members can move constructs or move assignments.

Move right value, copy left value

Strvec v1, v2;

V1 = v2; V2 is an lvalue, use Copy to assign the value

Strvec Getvec (IStream &)//getvec returns a right value

V2 = Getvec (CIN); Getvec (CIN) is the right value, using the Move assignment

Left and right values:

In the c++11 can take the address, has the name is the left value, conversely, cannot take the address, does not have the name is the right value (will the dead value or the pure right value). For example, int a = B+c, A is an lvalue, it has a variable named a, &a can get the address of the variable, the return value of the expression b+c, function int func () is an rvalue, and we cannot find it by the variable name until it is assigned to a variable.

If there is no move constructor, the right value is also copied. ( no move constructor defined, use move operation is actually implemented with copy constructor )

Classes that define a move constructor or move assignment operator must also define their own copy operations, otherwise these members are defined by default as deleted.

Recommendation: don't feel free to use the move action

It is not accessed until you are sure that the algorithm is assigning a value to an element or passing it to a user-defined function.

Use move carefully to improve performance significantly. Random use is likely to cause errors.

13.6.3 rvalue references and member functions

The overloaded functions that differentiate between moving and copying typically accept a const x& for one version, and another version to accept a t&&

Chapter 12 and 13 of the C++primer

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.