泛型句柄

泛型句柄与继承

在《句柄类与继承》http://blog.youkuaiyun.com/thefutureisour/article/details/7746582中,我们介绍过句柄。句柄其实就是一个复杂一点的智能指针,不仅在创建、复制、赋值,删除对象时,能够通过引用计数管理指针,而且通过动态绑定,实现了多态:既可以管理基类,可以管理派生类。但是它有一个小的缺陷,因为当时我们并没有介绍模板,所以这个句柄能管理的类型是固定的。如果我们新建立了一套继承派生体系,那么就要依葫芦画瓢的重新写一套句柄来管理它们。当我们介绍完模板之后,我们可以写一个“泛型句柄”类,当我们新建立了继承派生体系时,只需要把这个句柄加入到这个体系中就可以了。
先看看如果写这个类:

#ifndef HANDLE_H
#define HANDLE_H

template <class T> class Handle
{
public:
	//构造函数:空指针
	Handle(T *p = 0):ptr(p),use(new size_t(1)){}
	//重载解引和箭头操作符
	T& operator*();
	T* operator->();
	const T& operator*()const;
	const T* operator->()const;
	//复制构造函数
	Handle(const Handle& h):ptr(h.ptr),use(h.use){++*use;}
	//重载赋值操作符
	Handle& operator=(const Handle&);
	//析构函数
	~Handle(){rem_ref();};
private:
	//共享的对象
	T *ptr;
	//引用计数
	size_t *use;
	//删除指针的具体函数
	void rem_ref()
	{
		if(--*use == 0)
		{
			delete ptr;
			delete use;
		}
	}
};

template<class T>
inline Handle<T>& Handle<T>::operator=(const Handle &rhs)
{
	//右操作数引用计数+1
	++*rhs.use;
	//删除左操作数
	rem_ref();
	//具体对象的赋值
	ptr = rhs.ptr;
	use = rhs.use;
	return *this;
}

template <class T> inline T& Handle<T>::operator*()
{
	if(ptr)
		return *ptr;
	//空指针时抛出异常
	throw std::runtime_error("dereference of unbound Handle");
}

template <class T> inline T* Handle<T>::operator->()
{
	if(ptr)
		return ptr;
	//空指针时抛出异常
	throw std::runtime_error("access through unbound Handle");
}

template <class T> inline const T& Handle<T>::operator*()const
{
	if(ptr)
		return *ptr;
	throw std::runtime_error("dereference of unbound Handle");
}

template <class T> inline const T* Handle<T>::operator->()const
{
	if(ptr)
		return ptr;
	throw std::runtime_error("access through unbound Handle");	
}

#endif

稍微啰嗦两句:这个类模板的数据成员有两个:指向某个实际需要管理的类型的数据的指针以及它的引用计数。它定义了复制控制函数以及解引、箭头操作符。其中解引操作符返回的是实际需要管理的数据,而箭头操作符返回的是这个指针。

为了简单起见,我们用一个int型来说明这个指针是如何工作的:

int main()
{

	Handle<int> hp(new int(42));
	//新的作用域:作用域结束后会删除局部对象
	{
		Handle<int> hp2 = hp;
		cout<<*hp<<" "<<*hp2<<endl;
		*hp2 = 10;
	}
	cout<<*hp<<endl;
	return 0;
}

这个程序值得注意的地方在于人为的使用{}规定了一个作用域。第一次打印时,*hp和*hp2的值为42,*hp2赋值为10以后,*hp2被释放掉了,然后打印*hp时,由于这个两个指针指向同一个数,所以打印结果为10。
下面我们言归正传,看看如果把这个泛型句柄加入到《句柄类与继承》的Sales_item类中:


include "Item.h"
#include "Handle.h"



class Sales_item
{
public:
	//默认构造函数
	//指针置0,不与任何对象关联,计数器初始化为1
	Sales_item():h(){}

	//接受Item_base对象的构造函数
	Sales_item(const Item_base &item):h(item.clone()){}




	//重载成员访问操作符
	const Item_base *operator->()const
	{
		return h.operator->();
	}
	//重载解引操符
	const Item_base &operator*()const
	{
		return *h;
	}

private:
	Handle<Item_base> h;
};


由于我们并没有改变这个类的接口,所以其他的程序都不用修改(这里也没有贴出来)。我们只看看修改了什么:
首先由于我们定义了泛型句柄,所以这个类原来的指针和引用计数就不需要了,而换成了一个Handle类的实例。对应的,还要修改它的构造函数与复制控制部分。其中删除指针的操作由泛型句柄完成,这里也不需要了。
对于重载解引和箭头操作符,我们只要搞清楚我们自己想要的结果是什么,就能理解了:在原来的版本中,Sales_item对象的的解引将会或得Item_base 类的对象,箭头操作符返回指向Item_base 类的指针;因此,而在新的版本中,由于数据成员Handle<Item_base> h;的存在,我们的解引操作符返回的是*h,而箭头操作符返回的是h.operator->()。因为根据泛型句柄Handle的定义,对这个句柄对象解引返回就是实际需要管理的数据成员,对这个句柄对象进行箭头操作返回的就是指向它的指针。

【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其与遗传算法(GA)、标准粒子群算法等传统优化算法进行对比分析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和全局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究与改进中。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值