C ++ Primer Chapter XIII 13.1 copy assignment and destruction exercises and summary

We need to define a class explicitly or implicitly specified in the class copy assignment, move, what to do when destroyed,

We need to define copy constructor constructor move, copy assignment operators, assignment operators and mobile destructor to control these operations.

And moving the copy constructor initializes defines an object of the present object what to do.

Copy and move the assignment operator determines what to do when an object is assigned to another object of the same type.

Destructor defines what needs to be done when the object is destroyed.

These functions are called five members copying control operation.

13.1 copy, assignment and destruction

13.1.1 Copy constructor

What is the copy constructor?

If the first argument of the constructor is a type of reference type, and additional parameters have default values, then this function is a copy constructor.

The default copy constructor, when executed, all the non-static data members to present a copy of the object the object. If a class data member type, which copy constructor is executed, if the data member is a built-in type, the direct copy.

If the data member is an array type , one by one member of the array will be copied to the present subject. At other times, the array is not directly copied.

When executed copy initialization

= 1. When defining a variable
2. When one object to another object initialization
parameter a function of the type 3. A non-reference type, and argument passed is the object
4. Return Type non-reference type, returned when an object is
5. initialization list, a member of the class to initialize the array or polymeric.

Note copy initialization is sometimes called copy constructor, but sometimes the call is moving constructor

With focus, sometimes the compiler will skip the copy constructor, direct execution of ordinary constructor.

class A {
public:
	A(int i=1) :a(i) {
		cout<<"构造函数"<<endl;
	};
	A(const A& _a):a(_a.a) {
		cout << "拷贝构造函数" << endl;
	}
private:
	int a;
};

A a1 = 1;

In the book A a1 = 1; this definition is copy initialization variable manner, but in VS2017, the constructor is executed, and copy constructor can also be set to perform private.

However, the following scenario is executed by the constructor

A a(1);
A a2 = a;

Therefore, we can assume that the compiler use = dictation defined variable, if it contains the implicit conversion constructor is executed directly, instead of copying configuration.

So we can better understand why the explicit constructor when a time.

A a1 = 1;

It is wrong because the constructor is performed, but this time the constructor implicit conversion is not allowed.

This is what I get in VS2017 conclusions, or in specific books based on
all copies of the above five cases initialization that is performed when the constructor is explicit, can not be called when using the copy initialization = implicit conversion.

Another point, copy constructor parameter, typically const type, because it will not be modified when a copy of the object. And it is best not to copy constructor declared explict , otherwise use

A a(1);
A a2 = a;//报错

This takes the form variable error.

For standard library container, insert and push copy initialization is performed, and emplace () are directly initialized.

Exercise

13.1

When the first argument to the constructor of a class that is a reference type, and other parameters have default argument, the constructor is a copy constructor.

class A {
public:
	A(int i) :a(i) {
		cout<<"构造函数"<<endl;
	};
//private:
	A(const A& _a):a(_a.a) {
		cout << "拷贝构造函数" << endl;
	}
private:
	int a;
};

= 0. When using the variable definitions, I VS2017 in the case of using the definition of variables = constructor is invoked instead of the copy constructor, even if the copy configuration becomes private, the code can also normal operation

A a(1);
A a1 = 1;//VS2017下,显示的执行的是构造函数
A a2 = a1;//拷贝构造函数

1. This object using another object initialization

A a3(a2);

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

func(a2);

3. The non-return value of the function returns a reference to an object type

A fun_1() {
	A a(1);
	return a;
}
fun_1();

4. brace member list to initialize the array of elements or polymeric class.

A a(1);
A a2[] = {a,a,a,a,a};
13.2

According to the above definitions we know, our argument is passed an object, a type and function parameter when the non-reference type, this parameter will execute copy constructor.

If the copy constructor shape parameters and non-reference type, then that means we have to call the copy constructor to initialize the object, so that it becomes a cycle of death.

13.3

StrBlob only one data member

std::shared_ptr<vector<string>> data;

Therefore, when copying a StrBlob, initialize the data object is a data object of the present, since shared_ptr <vector <string >> is a class type, so that it is executed copy constructor. At this point they jointly safeguard the object reference count +

StrBlobPtr three data members

std::weak_ptr<vector<string>> wptr;
size_t curr;

StrBlobPtr copying objects and cur wptr values ​​for an object and wptr curr object of this initialization. size_t is built-in type, so the direct initialization, and wptr type is a class type, the class type of the executed copy constructor.

13.4

1. arg parameter of initialization copying is performed configured
2.local initialization
initializes the 3.head
4.pa array initialization
5. Return Type * heap

class A {
public:
	A(int i=1) :a(i) {
		cout<<"构造函数"<<endl;
	};
	A(const A& _a):a(_a.a) {
		cout << "拷贝构造函数" << endl;
	}
private:
	int a;
};

A global(1);
A  foo_bar(A arg) {
	A local = arg, *heap = new A(global);
	*heap = local;
	A  pa[4] = {local,*heap};
	return *heap;
}
13.5
class HasPtr {
public:
	HasPtr(const std::string& s = std::string()) :ps(new std::string(s)),i(0){};
	HasPtr(const HasPtr& hasptr):ps(new string(*hasptr.ps)),i(hasptr.i) {
		
	};
private:
	std::string *ps;
	int i;
};

13.1.2 assignment operator copies

We can define the copy assignment operator through, how they define a class type assignment.

Copy assignment operator = operator actually overloaded.

Operator + operator to use overloaded operators, operators operator + constituted with a function name defined functions, we need to define the parameter list and return values, some operators must be overloaded in the class, such as the assignment operator.

If the operator is a member function, then the call will be bound to the left operand on implicit this.

For the assignment operator, the right operand passed as a parameter explicit, the function returns a reference to the left side of the object.

For copy assignment operator, when using an object assigned to the object of the same type, if the data member is a class type, the execution of the data members copy assignment operator, if a built-in type, is performed built heart copy assignment operator . For the array as in the copy constructor, element-wise quality.

Exercise

13.6

Copy assignment operator, that is, the actual overload class assignment operator.

When the object assigned to the call assignment operator copies.

Called when one object to another using the same type of object assignment.

If we do not define the assignment operator, it will generate a synthetic copy of the assignment operator

13.7

For StrBlob, on assignment, the call assignment operator copies the data to assign a value to another object, and the two object points the object reference count +.

For StrBlobPtr, at the time of the assignment, respectively call

std::weak_ptr<vector<string>> wptr;
size_t curr;

curr ptr and the corresponding defined copy assignment operator type assignment. For wptr, it points to the same object reference count.

13.8
class HasPtr {
public:
	HasPtr(const std::string& s = std::string()) :ps(new std::string(s)),i(0){};
	HasPtr(const HasPtr& hasptr):ps(new string(*hasptr.ps)),i(hasptr.i) {
		
	};
	//列表初始化只能在构造函数中使用
	HasPtr& operator=(const HasPtr& p) {
		ps = new string(*p.ps);
		i = p.i;
	};
private:
	std::string *ps;
	int i;
};

13.1.3 destructor

Destructor action and resource objects are recovered, destroy the object.

+ Tilde and the class name is defined destructor, we want to do the operation performed before the object is released and destroyed in the destructor function.

Generally there will be a built-pointer delete dynamically allocated out.

If we only defined destructor, but the body of the function does nothing, after the function body destructor is finished, initialize the data members will follow Constructors reverse resources of non-static data members of the object to be recovered and destroyed.

This procedure is implicit, performed after the destructor function executor. If the data member type is a class, the data members need to be performed to destroy its destructor, if a built-in type, need not be performed destructor directly destroyed.

Note also built-pointer type, so if the data members, and we do not delete this pointer in the destructor operation by the pointer data member, then the pointer will only destroy themselves without destroying the object pointed.

When performing destructor

Word, the object is destroyed by the (end of life), the need to perform the destructor of the object.

Specifically
1. Non-static local variables out of scope
2. When the variable is destroyed, its members will be destroyed
when the container is destroyed 3. The
memory 4. The dynamically allocated, using the built-in pointer, delete the pointer
4. The temporary variable the end of the expression

Must remember to be recovered resources and destroy objects in the body of the function is not completed destructor, but performed after the completion of the destructor implicitly performed.

Now feeling the copy constructor, assignment and copy functions much like the destructor is the interface provided by C ++, we can not define himself, he will generate the default version, but we can also customize their operation.

Exercise

13.9

Class destructor is used to recover the resources allocated for the object, the object is destroyed. Instead it work configuration and constructors.

Synthesis constructors resource object for recovering and destroy non-static data members of the class

When not explicitly defined destructor, the compiler generates synthetic destructor /

13.10

StrBlob object calls the destructor destroyed when class type of data members, wherein the data members of the class data type, the call shared_ptr <vector <string >> destructor. If the data points of the object to the reference count is zero. Target data pointed to the destruction of

size_t type is not built-in type destructor, and wptr is a class type, the call weak_ptr <vector <string >> destructor, resource recovery destroy the object.

std::weak_ptr<vector<string>> wptr;
size_t curr;
13.11
	~HasPtr() {
		delete ps;
	}
13.12

Because the pointer is not necessary to call the built-in type destructor, so that a function call Oh, accum, item1, item2 destructor are performed, a total of three times.

13.13

Note that, for vec, when we push_back parameters, probably because of insufficient space currently allocated, so it is necessary to re-allocate space, then copied into the original elements, so there will be the implementation of the copy constructor and destructor, but this not every push_back such a situation occurs.

struct X {
	X() { cout << "X()" << endl; }
	X(const X&) {
		cout << "X(const X&)" << endl;
	};
	X& operator=(const X&) {
		cout<<"operator="<<endl;
	}
	~X() {
		cout << "~X()" << endl;
	}
};

void f(X x) {

}
void f1(X& x) {

}


测试代码
X x;//构造
	f(x);//拷贝构造
	f1(x);//没有
	auto p = new X();//构造
	vector<X> vec(20);//构造
	cout << vec.capacity() << endl;
	vec.push_back(x);//拷贝构造
	cout << vec.capacity() << endl;

13.1.4 three / five law

With the copy constructor, assignment function and copy destructor, we can get the copy control purposes.

Move constructor and move assignment function is a new standard added.

Typically we define destructor necessarily define a copy constructor and copy assignment function.

Because we defined destructor, which means by the dynamic allocation of memory. So also be dynamically allocated and configured in the copy references the copy.

Copy configuration generally defines the copy assignment to define, but is not necessarily required destructor, likewise, defines a copy assignment often require define a copy constructor, destructor but need not necessarily

Examples: a class each object requires a unique id label the object. This time we do not need a destructor

Exercise

13.14

Because of the use of synthetic copy constructor, so that only the data members of the object function is copied directly without any special operations, the only need is the same

13.15

Will change, since the operation is performed in a custom-defined copy constructor such that each object is identified by a unique serial number, and a non-reference type parameter, performs an incoming copy constructor so f (a), f (b), f © three resulting output is not required three objects.

13.16

Number output is a, b, c the number three. Because when the reference type parameter of type f, will not create the object function is called.

13.17
struct numbered {
	numbered() {
		num = cur_num;
		++cur_num;
	};
	numbered(const numbered&) {
		num = cur_num;
		++cur_num;
	};
	~numbered() {
		--cur_num;
	}
	int num;
	static int cur_num;
};
int numbered::cur_num = 0;

void f(const numbered& s) {
	cout << s.num << endl;
}

测试用例:
numbered a, b = a, c = b;
	f(a);
	f(b);
	f(c);

13.1.5 Use = default

If we do not define a copy constructor, assignment operator copies and destructors, C ++ compiler into one of us.

We can also use = default, explicitly tells the machine, using a synthetic version.

13.1. To prevent copy

Sometimes we do not want or assignment object can perform, such as a stream object.
May be modified by the past to the private copy constructor and copy assignment operator, this method can not be copied outside the class and assignment, but may be a member function and a friend class.

Therefore, the new C ++ standard introduced a = delete, will function as a function of defined functions.

struct A{
	A(const A&)=delete;
}

In addition to adding to the copy constructor and copy assignment function, the destructor = delete, we can use = delete any function, but the significance of doing that is not too large.

We generally do not set the destructor function deleted , because after doing so, the object can not release the resource objects and destroying objects up.

Here Insert Picture Description

Synthesized by the compiler copy control members may be deleted, which is reflected in, if the data object can not be a member of a default constructor, copy, reproduce, copy or destroy the control member will be defined deleted.

For example, class contains const or reference type but not within the class initialization data members.

struct A {
	const int a;
};

测试代码
A a;

The compiler error
Here Insert Picture Description

Exercise

13.18
struct Employee{
	Employee():_id(id) {
		++id;
	};
	Employee(const string& str) : _id(id), _name(str) { ++id; };
	Employee(const Employee& ee) = delete;
	Employee& operator=(const Employee& ee) = delete;
	int _id;
	string _name;
	static int id;
};
int Employee::id = 0;
13.19

Needs, but here I will copy constructor and copy assignment functions are defined to delete, because I think that an employee can not have two id.

13.20

Copy, assignment and destruction

TextQuery as data members

shared_ptr<std::vector<std::string>> file;
map<string,shared_ptr<set<line_no>>> wm.

Data member is QueryResult
Here Insert Picture Description
can see all class types, so when the copy, the copy execution of the respective function types. Performing assignment function of the respective categories of the assignment, when the destruction, the implementation of their destruction. For pointer type, performed after completion destructor, looks pointed object reference count is 0, 0 if the pointer points to release and remove the object.

13.21

No, because the class type of data members are all standard library, by the respective copy control function, and both classes are no built-pointers, smart pointers does not require manual maintenance release and the destruction of the pointing object.

Published 54 original articles · won praise 6 · views 3303

Guess you like

Origin blog.csdn.net/zengqi12138/article/details/104473152