管理资源类中定义swap函数

在管理资源的类中定义swap函数可以提高效率,避免不必要的内存分配。通过对比,自定义的swap函数在交换HasPtr对象时显著优于标准库的swap,尤其是在释放模式下,性能差距更为明显。
摘要由CSDN通过智能技术生成
    在管理资源的类中通常定义一个名为swap的函数,对于那些与重排元素顺序的算法一起使用的类,定义swap函数非常重要,这类算法在需要交换两个元素时会调用swap函数。如果一个类自己定义了一个swap函数,那么算法将使用自己定义的版本,否则算法将使用标准库定义的swap。虽然与往常一样我们不知道swap函数如何实现,但是理论上很容易理解,为了交换两个对象我们需要进行一次拷贝和两次赋值。例如交换类值HasPtr对象的代码可能像下面这样:
HasPtr temp = v1;   //创建v1的值的一个临时副本
v1 = v2;            //将v2赋值予v1
v2 = temp;          //将保存的v1的副本赋值予v2
这段代码将原来v1中的string拷贝两次(1)第一次是HasPtr的拷贝构造函数将v1拷贝给temp。(2)赋值运算符将temp赋予v2。将v2赋予v1的语句还拷贝了原来v2中的string。如我们所见,拷贝一个类值的HasPtr会分配一个新string并将其拷贝到HasPtr指向的位置。理论上这些内存分配都没有必要。我们希望swap交换指针,而不是分配string的新的副本。即,我们希望这样交换两个HasPtr:
string *temp = v1.str;     //为v1.str中的指针创建一个副本
v1.str = v2.str;           //将v2.str中的指针赋予v1.str
v2.str = temp;             //将保存的v1.str中原来的指针赋予v2.str
在我们自己定义的HasPtr类中,我们自己定义一个swap函数,而且我们使用自己定义的swap函数和标准库中swap函数做时间效率上的比较。首先我们把swap函数定义为friend,以便能访问HasPtr中的私有数据成员。由于swap的存在就是为了优化代码,且swap中的代码量比较少,所以我们将其声明为内联函数。swap函数体对给定对象的每个数据成员调用标准库swap。我们首先swap绑定到rhs和lhs的对象指针成员,然后是int成员。
#include<iostream>
#include<string>
#include<time.h>
using namespace std;

class HasPtr
{
private:
	int val;
	string *ps;
public:
	//默认构造函数
	HasPtr():val(0),ps(new string)
	{
	
	}
	//构造函数
	HasPtr(int v,string *p)
		:val(v),ps(new string(*p))
	{
	
	}
	//赋值构造函数
	HasPtr(const HasPtr &rsh)
		:val(rsh.val),ps(new string(*rsh.ps))
	{
	
	}
	//拷贝赋值运算符
	HasPtr& operator=(const HasPtr& rsh)
	{
		string *p =new string(*rsh.ps);
		delete ps;
		ps = p;
		val = rsh.val;
		return *this;
	}
	//析构函数
	~HasPtr()
	{
		delete ps;
	}
	friend void swap(HasPtr &lhs,HasPtr &rhs);
};

inline
void swap(HasPtr &lhr,HasPtr &rhs)
{
	std::swap(lhr.ps,rhs.ps);
	std::swap(lhr.val,rhs.val);
}

int main(void)
{
	string *ps1 = new string("hello1 world");
	string *ps2 = new string("hello2 world");
	HasPtr h1(3,ps1);
	HasPtr h2(4,ps2);
	clock_t start,end;
	start = clock();
	for(int i = 0; i < 10000000; ++i)
	{
		swap(h1,h2);
		//std::swap(h1,h2);     //使用标准库中的swap函数
	}
	end = clock();
	cout<<"时间:"<<float(end - start)/CLOCKS_PER_SEC*1000<<"ms"<<endl;

	system("pause");
	return 0;
}
在vs08的debug下运行结果:(我们交换两个HasPtr对象10,000,000次)
使用标准库中的swap函数运行时间:41939ms
使用我们自己定义的是swap函数运行时间:853ms
在vs08的release下运行结果:(我们交换两个HasPtr对象10,000,000次)
使用标准库中的swap函数运行时间:25939ms
使用我们自己定义的是swap函数运行时间:13ms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值