Effective C++ Item 25 考虑写出一个不抛异常的swap函数

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常

示例:

stl里的swap算法

namespace std{
	template<typename T>
	void swap(T &a, T &b){
		T temp(a);
		a = b;
		b = temp;
	}
}

//“pimpl手法”(pointer to implementation) --> 文件间的编译依存度
class WidgetImpl{
public:
	//...
private:
	int a, b, c;
	std::vector<double> v;
	//...
}

class Widget{
public:
	Widget(const Widget &rhs);
	Widget &operator=(const Widget &rhs){ //返回的为什么是引用?--> 就应该是引用,参见Item10令operator=返回一个reference to *this。
										  //这里和Item28不一样,那里说的是不要返回handler指向对象 内部 成分。
		//...
		*pImpl = *(rhs.pImpl);
		//...
	}
	//...
private:
	WidgetImpl *pImpl;
}

解析:一旦要转换两个Widget对象值,我们唯一需要做的就是转换其pImpl指针,但缺省的swap算法不知道这一点。它不只复制三个Widgets,还复制三个WidgetImpl对象。

纠正:将std::swap针对Widget特化

通常我们不被允许改变std命名空间的任何东西,但可以为标准template制造特化版本

namespace std{ //这是std::swap针对“T是Widget”的特化版本。目前还不能通过编译
	template<>
	void swap<Widget>(Widget &a, Widget &b){
		swap(a.pImpl, b.pImpl);
	}
}

经验:如果你提供一个member swap,也该提供一个non-member swap用来调用前者。对于 classes(而非templates),也请特化std::swap

示例:

namespace WidgetStuff{
	class Widget{  //能正常编译,且与STL容器有一致性。因为所有STL容器也都提供有public swap成员函数和std::swap特化版本
	public:
		//...
		void swap(Widget &other){ //调用swap时应针对std::swap使用using声明式,然后调用swap并且不带任何“命名空间资格修饰”
			using std::swap;
			swap(pImpl, other.pImpl);
		}

		//...
	};
	void swap(Widget &a, Widget &b){ //non-member swap 函数;这里并不属于std命名空间
		a.swap(b);
	}
}
namespace std{
	template<>
	void swap<Widget>(Widget &a, Widget &b){
		a.swap(b);
	}
}

经验:为“用户定义类型”进行std templates全特化是好的,但千万不要尝试在std内加入某些对std而言全新的东西

示例:

template<typename T>
class WidgetImpl{
	//...
}
template<typename T>
class Widget{
	//...
}

namespace std{ //错误,不合法 --> function template只能全特化,不能偏特化
	template<typename T>
	void swap<Widget<T> >(Widget<T> &a, Widget<T> &b){
		a.swap(b);
	}
}

namespace std{
	template<typename T> //std::swap的一个重载版本,不合法 --> std不允许添加新的的templates
	void swap(Widget<T> &a, Widget<T> &b){
		a.swap(b);
	}
}

Effective C++ Item 25 考虑写出一个不抛异常的swap函数,布布扣,bubuko.com

时间: 2024-12-30 13:22:03

Effective C++ Item 25 考虑写出一个不抛异常的swap函数的相关文章

条款25:考虑写出一个不抛异常的swap函数

条款25:考虑写出一个不抛异常的swap函数 swap函数在C++中是一个非常重要的函数,但实现也非常复杂. 看一个缺省的std::swap函数的实现 namespace std { template<typename T> void swap( T& a , T& b) { T temp(a); a = b; b = temp } } ①内置类型的调用 int a = 2; int b =3; std::swap(a, b); cout<<"a:&quo

EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数

记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于classes(而非templates),也请特化std::swap ★调用swap时应针对std::swap使用using声明式,然后调用swap并且不带任何“命名空间资格修饰” ★为“用户定义类型”进行std templates全特化是好的,但千万不要尝试在std内加入某些对std而言全新的东西 --

《Effective C++》item25:考虑写出一个不抛异常的swap函数

std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _TCHAR* argv[]) { int a[10] = {1,2,3,4,5,6,7,8,9,10}; vector<int> vec1(a, a + 4); vector<int> vec2(a + 5, a + 10); swap(vec1, vec2); for (int i =

Effective C++:条款25:考虑写出一个不抛异常的swap函数

(一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& b) { T temp(a); a = b; b = temp; } } 这个函数是异常安全性编程的核心,而且是用来处理自我赋值可能性的一个常见机制 可是对某些类型而言,这些复制动作无一必要:当中基本的就是"以指针指向一个对象,内含真正数据"那种类型.多为"pimpl手

[Effective C++ --025]考虑写出一个不抛异常的swap函数

引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: 1 namespace std { 2 template<typename T> 3 void swap(T &a, T& b) 4 { 5 T temp(a); 6 a = b; 7 b = temp; 8 } 9 } 只要类型T支持拷贝(通过拷贝构造函数和拷贝赋值操作符完成),那么这个版本的

Effective C++ -----条款25:考虑写出一个不抛异常的swap函数

当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常. 如果你提供一个member swap,也该提供一个non-member swap用来调用前者.对于class(而非templates),也请特化std::swap. 调用swap时应针对std::swap使用using声明式,然后调用swap并且不带任何“命名空间资格修饰”. 为“用户定义类型”进行std templates全特化是好的,但千万不要尝试在std内加入某些对std而言全新的东西.

Effective C++ 条款25 考虑写出一个不抛出异常的swap函数

1. swap是STL的一部分,后来成为异常安全性编程(exception-safe programming)(见条款29)的一个重要脊柱,标准库的swap函数模板定义类似以下: namespace std{ template<typename T> swap(T& lhs,T& rhs){ T temp(lhs); lhs=rhs; rhs=temp; } } 只要T类型支持拷贝构造以及拷贝赋值,标准库swap函数就会调用T的拷贝构造函数和拷贝构造操作符完成值的转换,但对于某

Effective C++笔记_条款25考虑写出一个不抛出异常的swap函数

1 // lib中的swap 2 namespace std { 3 template<typename T> 4 void swap (T& a, T& b) 5 { 6 T temp(a); 7 a = b; 8 b = temp; 9 } 10 } 11 12 // 缺点:需要赋值大量的数据,但是有的时候并不要复制如此多的内容 13 class WidgetImpl { 14 public: 15 //... 16 private: 17 int a, b, c; 18

《Effective C 》资源管理:条款25--考虑写出一个不抛出异常的swap函数

条款25考虑写出一个不抛出异常的swap函数 条款25:考虑写出一个不抛出异常的swap函数 swap是STL中的标准函数,用于交换两个对象的数值.后来swap成为异常安全编程(exception-safe programming,条款29)的脊柱,也是实现自我赋值(条款11)的一个常见机制.swap的实现如下: namespace std{ template<typename T> void swap(T& a, T& b) { T temp(a); a=b; b=temp;