C ++ 프라이머 장 XIII 13.3 연습 및 교환 요약

13.3 교환 작업

자원의 클래스 관리를 위해, 일반적으로 스왑 함수를 정의 할 필요가 (나의 이해는 클래스 동적으로 할당 된 메모리의 데이터 멤버가 있다는 것입니다).

기본 스왑은 이것이다 :

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

코드는 임시 변수를 생성하고,이 개 과제를 사용합니다.

당신이 객체의 객체가 매우 큰 메모리에 대한 포인터가있는 경우에 대해 생각해보십시오. 이 임시 변수가 더 소비 성능입니다 만듭니다.

**이 임시 변수를 만들 수 있지만 두 개체 내에서 데이터를 교환하지 않습니다. 13.30 **으로 연습 스왑에 표시

당신이 효율성을 향상시킬 수있는이 방법은 물론, 이 최적화의 수단 필요가 없습니다 .

우리는 클래스가 스왑의 자체 버전을 정의 정의하면, 그 알고리즘은 스왑의 사용을 요구, 스왑는 우리 자신의 정의를 호출하는 우선 순위를 부여합니다.

할당 연산자를 이용하여 스왑에서

코드를 작성하기 전에, 할당 연산자는 부주의의 일부를 작성하는 것을 잊지 수있는 반면, 작업 및 소멸자 건축을 복사 완료 할 필요성을 이해할 수있다.

이 문제에 대해 걱정하지 않아도됩니다 스왑을 사용합니다. 아래 그림과 같이
그림 삽입 설명 여기
우리가 변경해야 원래의 이야기가 아닌 참조 매개 변수 참조 형이된다. 함수 호출은 소멸자를 호출 한 후이 시점에서, 두 객체의 교환 후, A는 우이 기능을 호출되는 인수의 복사합니다.
그리고 *이 객체는 전에 우를 저장됩니다.

우리는 고려 여부를 알 수 없도록하는 것은 자기 지정하고 개체 포인터 유형의 데이터 멤버가이 객체 포인트를 * 해제 할 필요성을 고려한다.

유일한 단점은 비 참조 형 매개 변수를 만들 필요가있을 수 있습니다.

연습

13.29

스왑 함수에 스왑 함수 호출은 같은 기능이지만 아니기 때문에 오버로드 기능 자연 공통 함수를 호출하고, 스왑에서 차이가 없습니다

13.30

작성하기 전에 HasPtr은 테스트되지 때문에 그래서 지금 개정에 새 문자열 (에 전달 된들)을 잊지

일부 알고리즘에서 우리는 기능 요소가 호출됩니다 이동해야합니다.

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

다음 정렬 알고리즘은 적은 수의 매개 변수로 인해 용기의 거의 하나님을 아는 해석에 따라 스왑 기능이 호출되지 정렬 사용되는 종류의 삽입은 그래서 통화 스왑 기능이있는 경우 요소를 더 빠른 정렬이 호출되지 않은이 그것은 스왑 시간을 호출;

거의 설명을 알고

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;
	}

다음 코드 1000 개 요소 다음 함수 호출의 추가 스왑

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

기타 대답 : 아무 혜택이없는, 그래서 그들이 할당 동적 메모리 할당을 포함하지 않기 때문에

그러나 나는 우리가 많은 혜택을 한 후, 임시 객체에게 스왑을 작은 가격을 다시 만들 수 있지만, 혜택을 누릴 수 있다고 생각하지만, 우리가 할당 문에 스왑을 사용하는 경우, 그것은 크게 코드의 양을 줄일 수 있고, 코드가 예외 안전합니다.

예외 여기 안전, 우리가 개체를 수정할 때 얘기 예외가 발생했을 경우, 그들은 데이터가 방해되지 않도록 할 방법을 프로그래머.

내가 하나, 우리는 삭제가 일어날 쓸 수 있습니다 이해하지만 스왑 기능, 우리는이 문제를 고려하지 않는, 두 번째는 예외가 발생하지 않도록 스왑은 새로운 것이 아니다이다. 스왑 그래서 코드는 예외 안전합니다. (견적은 또한 비정상적인 보안을 무엇을 의미하는지 이해하기 위해 더 많은 연습을 필요로 이해하지 않는다)

다음 코드 예제는 다음과 같이 다시 쓸 수 :

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;
};

** 이런 식으로, 당신은 코드가 크게 감소보고, 우리는 시간의 코딩에서 삭제 객체를 잊지 방지 할 수 있습니다.
P 개의 기능이 완료된 후에 실행되기 때문에, 소멸자를 호출한다. **

물론, 여기가 아닌 형식 매개 변수 참조의 형태가 정말 성능의 관점 어떠한 혜택에서 사본을 수행해야된다. 그러나 간단한 코드 재사용의 관점에서, 또는 혜택을 아

HasPtr& operator=(HasPtr p) {
	swap(*this, p);
	return *this;
};
게시 54 개 원래 기사 · 원 찬양 6 · 보기 (3301)

추천

출처blog.csdn.net/zengqi12138/article/details/104498855