zoukankan      html  css  js  c++  java
  • 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++必知必会》一个指向成员的指针并不指向一个具体的内存地址,它指向的是一个类的特定成员,而不是指向一个特定对象里的特定成员。)

    HandlerDescriptor


    下面是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;
    }
    
  • 相关阅读:
    为什么项目经理非常难有节操的选举
    二叉查找树的删除操作
    二叉查找树的前驱后继
    替罪羊树
    树链剖分
    DFS序
    bzoj3224: Tyvj 1728 普通平衡树(平衡树)
    splay树入门(带3个例题)
    红黑树
    AVL树
  • 原文地址:https://www.cnblogs.com/oloroso/p/4596836.html
Copyright © 2011-2022 走看看