Essential C++学习记录&笔记整理40(实现一个模板类)

关于new表达式

  • new表达式可分解为两个操作:
    ①向程序的空闲空间请求内存,若分配到足够空间,则返回指针,指向新对象;若未分配到足够空间,则抛出异常bad_alloc(异常处理)
    ②如果new 类型名(初值),则该新对象被初始化。
    举个class类型的例子:
_root = new BTnode<elemType>(elem);

其中elem被传入BTnode模板类的类构造函数。分配内存失败,初始化操作(类构造函数操作)不会发生。

模板类成员函数的定义/声明实战:

举几个例子吧,主要为了熟悉语法!
一般模板类成员函数(看看格式就好,不必计较太多)定义:

template<typename valType>
void BTnode<valType>::
insert_value(const valType &val)//注意这里的格式
{
	if(val==_val)
	{
		_cnt++;
		return;
	}//二叉树有这个结点了,就把结点插入次数记录下来即可
	if(val<_val)
	//插入的结点比当前结点小,就插到当前结点的左孩子(如果当前结点的左孩子没有)
	{
		if(!_lchild)
		{
			_lchild=new BTnode(val);
		}
		else//当前结点的左孩子有了,插入到当前结点的左孩子的左孩子或右孩子结点
		{
			_lchild->insert_value(val);//递归调用去插入到当前结点的左孩子的左孩子或右孩子结点
		}
	}
	else
	//插入的结点比当前结点大,就插到当前结点的右孩子(如果当前结点的右孩子没有)
	{
		if(!_rchild)
		{
			_rchild=new BTnode(val);
		}
		else
		{
			_rchild->insert_value(val);
		}
	}
}

内联模板类成员函数(看看格式就好,不必计较太多)定义:

template<typename elemType>
inline void BinaryTree<elemType>::
remove(const elemType &elem)//注意这里的格式!
{
	if(_root)
	{
		if(_root->_val==elem)
		{
			remove_root();
		}
		else
		{
			_root->remove_value(elem,_root);
		}
	}
}

一般模板类成员函数的声明:

template<typename valType>
void BTnode<valType>::
remove_value(const valType &val,BTnode *&prev);
//关于*&的解释下面有说

模板类成员函数的定义/声明格式

OK,摸清楚大概格式了。即

注意分三行写这种让代码清晰简洁的写法👇

template<typename 自定义类型名(占位符)>
(自己决定这里加不加inline) 返回类型 模板类类名<自定义类型名>::
模板类成员函数名(参数表(比如const 自定义类型名 &参数名等));或者{//。。。}

函数参表出现了*&的说明

  • 复习一下,参表的参数以&方式传递,为了避免当模板自定义类型名(<typename 巴拉巴拉>中的巴拉巴拉)被指定为class类型时,因传值(不带&)而产生的昂贵复制开销。
  • 不改变参数值,就再该参数名的声明最前加个const,即const 类型名 参数名…
  • *&即为指针的引用
  • *&出现在函数参表中的意思就是我**既想改变传入形参的实参指针(或说形参指针)所指的对象,又想改变实参(或说形参)指针本身**
  • 实例:
template<typename valType>
void BTnode<valType>::
remove_value(const valType &val,BTnode *& prev)//删除二叉树的一个结点(非根结点)
//根结点删除另有其他BTnode类成员函数去管,这里不用多虑
{
//在二叉树中自顶向下搜索要删除的结点
	if(val<_Val)
	{
		if(!_lchild)
		{
			return;
		}
		else
		{
			_lchild->remove_value(val,_lchild);
		}
	}
	else if(val>_val)
	{
		if(!_rchild)
		{
			return ;
		}
		else
		{
			_rchild->remove_value(val,_rchild);
		}
	}
	else//找到要删除的二叉树的结点了
	{
		if(_rchild)
		{
			prev=_rchild;//这里改变了形参(实参)指针的指向,即“又想改变实参(或说形参)指针本身”
			//*prev=....可以理解为想改变传入形参的实参指针(或说形参指针)所指的对象
			//(需要有重载运算符=,而且是模板函数形式的重载运算符函数,下节会说)
			if(_lchild)
			{
				if(!prev->_lchild)
				{
					prev->_lchild=_lchild;
				}
				else
				{
					BTnode<ValType>::lchild_leaf(_lchild,prev->_lchild);
				}
			}
		}
		else
		{
			prev=_lchild;
		}
	}
	delete this;//删除二叉树中我想删除的结点(即一个BTnode类类对象)
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值