6 HandlerDescriptor 处理程序描述类——Live555源码阅读(一)基本组件类

这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类。

本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso/

HandlerDescriptor 处理程序描述类

HandlerDescriptor类是一个很重要的类,其保存了处理程序的函数指针和相关的数据的地址。在构建处理任务的时候,会使用到这个类的对象,处理任务的时候也会用到。

HandlerDescriptor类同时将HandlerIterator类和HandlerSet类声明为友元类,方便了后面链表的操作。个人觉得这种封装方式不是特别好。只是个人看法而已。

这里的封装还有一个原因就是因为构造和析构都是private权限的,因为只能在其友元类HandlerSet中来调用,避免暴露接口。

这里要特别提一下数据成员socketNum和conditionSet。socketNum在链表中要来标识一个节点,那么这socketNum的值是如何赋值来的呢?这里先提一下,在使用到这个类对象的时候,会将一个socket套接口作为其值(windows下是SOCKET类型linux/unix下是文件描述符,其实质都是int类型),它必然是唯一的。这个变量名取为socketNum就是因为后面它将用于网络。而conditionSet是条件集合的意思,用来标识对应socketNum代表的套接口可以采取那写操作(读/写/异常)。

还有注意的是handlerProc的类型是一个类成员函数指针,它应该指向一个TaskScheduler的函数成员地址。(《C++必知必会》一个指向成员的指针并不指向一个具体的内存地址,它指向的是一个类的特定成员,而不是指向一个特定对象里的特定成员。)

6 HandlerDescriptor 处理程序描述类——Live555源码阅读(一)基本组件类

6 HandlerDescriptor 处理程序描述类——Live555源码阅读(一)基本组件类


下面是HandlerDesciptor类的定义

// 处理程序描述类(作为链表的节点)
class HandlerDescriptor {
//构造和析构都是private权限的,因为只能在其友元类HandlerSet中来调用
// 如果nextHandler为其自身,自身就是双向链表的头结点
// 否则将自身插入到nextHandler和nextHandler->fPrevHandler之间
HandlerDescriptor(HandlerDescriptor* nextHandler);
// 将自身从双向链表中移除。这个函数一般由delete操作来调用
virtual ~HandlerDescriptor();
public:
int socketNum; //socket在链表里面用来标识节点
int conditionSet; //条件集合
//typedef void BackgroundHandlerProc(void* clientData, int mask);
TaskScheduler::BackgroundHandlerProc* handlerProc; //后台处理程序函数指针
void* clientData; //客户端数据
private:
// Descriptors are linked together in a doubly-linked list:
friend class HandlerSet;
friend class HandlerIterator;
HandlerDescriptor* fNextHandler; //下一个处理程序描述
HandlerDescriptor* fPrevHandler; //上一个处理程序描述
};

HandlerDescriptor的构造函数

从其构造函数可以看出,其默认只被用于链表中作为节点存在。并且这个构造函数是private权限的,只有在本类或者友元类中可以使用其来构造对象。

HandlerDescriptor::HandlerDescriptor(HandlerDescriptor* nextHandler)
: conditionSet(0), handlerProc(NULL) {
// Link this descriptor into a doubly-linked list:
if (nextHandler == this) { // initialization
fNextHandler = fPrevHandler = this;
} else {
fNextHandler = nextHandler;
fPrevHandler = nextHandler->fPrevHandler;
nextHandler->fPrevHandler = this;
fPrevHandler->fNextHandler = this;
}
}

HandlerDescriptor的析构

必须说一下,这里析构不是简单的释放自身,这里将节点从链表中移除了。想一想,如果是头结点呢?也是没有问题的,只是操作之后并没有从链表移除。对头结点而言在析构结束后,就是整个链表的释放。

HandlerDescriptor::~HandlerDescriptor() {
// Unlink this descriptor from a doubly-linked list:
fNextHandler->fPrevHandler = fPrevHandler;
fPrevHandler->fNextHandler = fNextHandler;
}
上一篇:将通过上传的txt文件存储在localStorage,提取并构建File对象


下一篇:JavaScript从初见到热恋之深度讨论JavaScript中的面向对象。