C ++ Primer Chapter XIII 13.3 exercises and exchange summary

13.3 exchange operation

For class management of resources (my understanding is that the data members of the class dynamically allocated memory), generally you need to define a swap function.

The default swap is this:

A temp = v1;
v1=v2;
v2=temp;

Code creates a temporary variable, and use two assignments.

Think about if you have a pointer to a memory for very large objects in an object. This creates a temporary variable is more consumption performance.

** it does not create temporary variables, but only exchange data inside the two objects. 13.30 ** As shown in practice swap

This way you can improve the efficiency, of course, this is not necessary, only a means of optimization .

If we define a class defines its own version of the swap, then those algorithms require the use of swap, the swap will give priority to call our own definition.

In the swap using the assignment operator

Before writing code, the assignment operator can understand the need to complete the work and destructors copy construction, while it might forget to write part of carelessness.

Use the swap can not worry about this problem. As shown below
Here Insert Picture Description
we need to change the original talk becomes non-reference parameter reference type. At this point, after the exchange of two objects, a copy of the argument RHS is called function, after the function call calls the destructor.
And * this object is saved rhs before.

So we do not know whether to consider is self-assignment and consider the need to release the object pointer type data members * this object points to.

The only drawback may be that you need to create a non-reference type parameter.

Exercise

13.29

Because the swap function call to the swap function is not the same function but overloaded function , which calls a common function in nature and there is no difference in swap

13.30

Since before written HasPtr not been tested so forget the s passed to the new string () in the now revised

In some algorithms we need to move the function element will be called.

class HasPtr {
	friend void swap(HasPtr& obj1, HasPtr& obj2);
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) {
		auto temp = new string(*p.ps);
		delete ps;
		ps = temp;
		i = p.i;
		return *this;
	};
	~HasPtr() {
		delete ps;
	}
	string desc() {
		std::ostringstream str("");
		str << "ps:" << *ps << ",i:" << i;
		return str.str();
	}
private:
	std::string *ps;
	int i;
};
void swap(HasPtr& obj1, HasPtr& obj2) {
	using std::swap;
	swap(obj1.ps,obj2.ps);
	swap(obj1.i,obj2.i);
	cout << "HasPtr::swap(HasPtr& obj1, HasPtr& obj2)" << endl;
}
13.31

The following sorting algorithm is not called swap function according to the interpretation know almost god of the container which is due to fewer parameters, sort insertion sort is used so there is no call swap function is invoked if the elements more quick sort, this It calls swap time;

Know almost explanations

vector<HasPtr> vec = {string("adsf"),string("sdf"),string("jocl"),string("123"),string("sdf")};
	std::sort(vec.begin(), vec.end());
	for (const auto& item:vec) {
		cout << item.desc() << endl;
	}

The following code adds 1000 elements, then the function call swap

vector<HasPtr> vec = {string("adsf"),string("sdf"),string("jocl"),string("123"),string("sdf")};
	for (int i = 0; i < 1000;++i) {
		vec.push_back(string("asd"));
	}
	
	std::sort(vec.begin(), vec.end());
13.32

Others answer: because they do not involve dynamic memory allocation in the assignment so there is no benefit

But I think we can benefit from, although re-create a temporary object a small price, then swap to benefit much, but if we use the swap in the assignment statement, it can significantly reduce the amount of code, and the code is exception-safe.

Exception safety here, we are talking about when modifying an object, if an exception occurs, the programmer how they should do so that data is not disturbed.

I understand one is, we may write delete happen, but the swap function, we do not consider this, the second is the swap is not new, so the exception does not occur. So swap, the code is exception-safe. (Estimate does not understand, you also need more practice to understand what it means abnormal security)

The following code example be rewritten as:

HasPtr& operator=(const HasPtr& p) {
	++*p.ref_count;
	if (--*ref_count==0) {
		delete ps;
		delete ref_count;
	}
	ps = p.ps;
	ref_count = p.ref_count;
	i = p.i;
	return *this;
};

** like this, you can see the code significantly reduced, and avoid we forget delete objects in the coding of the time.
Since the p function is executed after completion, will call the destructor. **

Of course, here it becomes a form of non-formal parameter references need to perform a copy, from a performance standpoint really no benefit. But from the point of view of simple code reuse, or benefited ah

HasPtr& operator=(HasPtr p) {
	swap(*this, p);
	return *this;
};
Published 54 original articles · won praise 6 · views 3301

Guess you like

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