Copy control, Beibei Machine Controller

Source: Internet
Author: User

Copy control, Beibei Machine Controller

When defining a class, we explicitly or implicitly specify what to do when copying, moving, assigning, and destroying this type of object. A class controls these operations by defining five special member functions, including copy constructor and copy-assignment operator), move constructor, move-assignment operator, and destructor ). The copy and move constructors define what to do when another object of the same type is used to initialize the object. The copy and move assignment operators define what an object will do when it is assigned to another object of the same type. Destructor define what to do when this type of object is destroyed. These operations are called copy control ).

1. copy constructor-if we do not define a copy constructor for a class, the compiler will automatically define a copy constructor for us.

Class Foo {public: Foo (); // default constructor Foo (const Foo &); // copy constructor} string dots (10 ,'. '); // directly initialize string s (dots); // directly initialize string s2 = dots; // copy and initialize string null_book = "9-999-99999-9 "; // copy initialization string nines = string (100, '9'); // copy Initialization

When direct Initialization is used, the compiler uses normal function matching to select the constructors that best match the provided parameters. When we use copy initialization, the compiler copies the right operation object to the object being created. If necessary, type conversion is required.

2. Copy value assignment operator-merge and copy

Class Foo {public: Foo & operator = (const Foo &); // value assignment operator}

3. destructor -- The compositing destructor does not delete a pointer data member.

Class Foo {public :~ Foo (); // destructor}

Rules 3/5

1) classes requiring destructor must also be copied and assigned values.
2) classes that require copy operations also need to be assigned values, and vice versa.

Use default: When we use = default to modify the declaration of a member in the class, the synthesized function is implicitly declared as inline, and = default is used for the member's out-of-class definition, just like what the copy assignment operator does.

Delete is used to prevent copying and assigning values. You cannot delete destructor.

Private copy control: the copy constructor and the copy assignment operator are declared as private to prevent copying. Declare the copy control members as private, but do not define them.

Copy control and Resource Management: Generally, classes of resources outside the management class must define copy control members. Copy semantics: 1. Class behavior is like a value; 2. Class behavior is like a pointer and shared state.

1. The behavior of a class is like a value.
Hasptr needs:
1. Define a copy constructor to copy the string, instead of copying the pointer.
2. Define a destructor to release the string
3. Define a copy value assignment operator to release the current string of the object, and copy the string from the right operation object

Class Hasptr {public: Hasptr (const std: string & s = std: string (): ps (new std: string (s), I (0) {} Hasptr (const Hasptr & p): ps (new std: string (* p. ps), I (p. i) {} Hasptr & operator = (const Hasptr &);~ Hasptr () {delete ps;} private: std: string * ps; int I ;}; Hasptr & Hasptr: operator = (const Hasptr & rhs) {auto newp = new string (* rhs. ps); // copy the underlying string and perform the auto-assigned delete ps operation; ps = newp; I = rhs. i; return * this ;}

2. Class defining behavior like pointer
For classes that behave like pointers, we need to define the copy constructor and the copy value assignment operator for them to copy the pointer member itself rather than the string it points. Our class still needs our own destructor to release the memory of the constructor that accepts string parameters. However, the Destructor cannot unilaterally release the associated string. The string can be released only when the last Hasptr pointing to the string is destroyed.

Define a class that uses reference count

Class Hasptr {public: Hasptr (const std: string & s = std: string (): ps (new std: string (s), I (0 ), use (new std: size_t (1) {} Hasptr (const Hasptr & p): ps (new std: string (* p. ps), I (p. i), use (p. use) {++ * use;} Hasptr & operator = (const Hasptr &);~ Hasptr () {} private: std: string * ps; int I; std: size_t * use; // used to record how many objects share * ps members };

Copy member "tampering" reference count of class pointer

Hasptr ::~ Hasptr () {if (-- * use = 0) {delete ps; // release string memory delete use; // Release counter memory} Hasptr & Hasptr :: operator = (const Hasptr & rhs) {++ * rhs. use; // increment the reference count of the right operation object if (-- * use = 0) {delete ps; // if no other user exists, delete use;} ps = rhs. ps; I = rhs. i; use = rhs. use; return * this ;}

Switch operation-swap, swap two elements, the swap function should call swap, instead of std: swap

Class Hasptr {friend void swap (HasPtr &, HasPtr &) ;}_ inline void swap (Hasptr & lhs, Hasptr & rhs) {using std: swap; swap (lhs. ps, rhs. ps); // exchange pointer instead of string data swap (lhs. i, rhs. i); // exchange int members}

Each swap call should be unrestricted. That is, each call should be a swap, not a std: swap. If a specific type of swap version exists, the matching degree is better than that defined in std. Similarly, swap is used in the assignment operator.

// Note that rhs is passed by value, which means the HasPtr copy constructor
// Copy the string in the right operation object to rhs

Hasptr & Hasptr: operator = (const Hasptr & rhs) {swap (* this, rhs); // rhs now points to the memory used by this object and return * this; // rhs is destroyed and the pointer in rhs is deleted}

Object movement: 1. In the process of re-allocating memory, it is unnecessary to copy elements from the old memory to the new memory. A better way is to move elements. 2. Another reason for using move instead of copy is the IO class or unique_ptr class. These classes contain resources that cannot be shared (such as pointers or IO buffering ). Therefore, these types of objects cannot be copied but can be moved.

1. Right Value reference ). Get the right value reference through & instead of &. the right value can only be bound to one object to be destroyed. The left value has a persistent state, while the right value is either a literal constant or a temporary object created during expression evaluation. The object referenced by the right value will be destroyed, and there are no other users in the object. The Code referenced by the right value can take over the resources of the referenced object freely.

Int I = 42; int & r = I; // correct: r references iint & rr = I; // error: you cannot bind a right value reference to an int & r2 = I * 42; // error: I * 42 is a right value const int & r3 = I * 42; // correct: We can bind a const reference to a right value int & rr2 = I * 42; // correct; Bind rr2 to the multiplication result

The standard library move function is defined in the header file utility.

int &&rr3=std::move(rr1);    //ok

Move tells the compiler that we have a left value, but we want to process it like a right value. We must realize that calling move means committing that we will no longer use rr1 in addition to assigning values to or destroying it. After moving is called, we cannot make any assumptions about the value of the source object after moving.

The moving constructor and the moving value assignment operator must specify notest in the Class header file declaration and definition (if not.

Class StrVec {public: StrVec (StrVec &) now.t; // mobile constrfunction} StrVec: StrVec (SteVec & s) now.t: elements (s. elements), first_free (s. first_free), cap (s. cap) {// make s enter this state-it is safe to run the Destructor on it. elements = s. first_free = s. cap = nullptr;} StrVec & StrVec: operator = (StrVec & rhs) now.t {// directly checks the self-assigned value if (this! = & Rhs) {free (); // release existing element elements = rhs. elements; // take over resources from rhs first_free = rhs. first_free; cap = rhs. cap; // place rhs in the destructible state rhs. elements = rhs. first_free = rhs. cap = nullptr;} return * this ;}

Only when a class does not define any version of the copy control member, and each non-static data member of the class can be moved, the compiler will synthesize a mobile constructor or a mobile assignment operator for it. The compiler can move members of the built-in type. If a member is of the class type and has a corresponding moving operation, the compiler can move the member:

// The compiler will merge and move the struct X {int I for X and hasX; // the built-in type can move std: string s; // string defines your own mobile operations} struct hasX {X mem; // X has a merged mobile operation} X x, x2 = std: move (X ); // use the merged mobile constructor hasX hx, hx2 = std: move (hx); // use the merged mobile Constructor

In addition,

HasY (hasY &) = default; // hasY will have a removed mobile Constructor

If a class has both a mobile constructor and a copy constructor, the compiler uses common function matching rules to determine which constructor to use. The assignment operation is similar.
1. Move the right value and copy the left value.
2. If no constructor is moved, the right value is also copied.

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: 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.