26 BasicUsageEnvironment基本使用环境——Live555源码阅读(三)UsageEnvironment

这是Live555源码阅读的第三部分,包括了UsageEnvironment相关的三个类。

本文由乌合之众 lym瞎编,欢迎转载 blog.cnblogs.net/oloroso

本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso

简介

这个类很简单,它不想basicTaskScheduler那么复杂。没有增加任何成员,仅是实现了基类的几个纯虚方法。

以下是其定义

class BasicUsageEnvironment : public BasicUsageEnvironment0 {
public:
static BasicUsageEnvironment* createNew(TaskScheduler& taskScheduler); // redefined virtual functions:
virtual int getErrno() const; // 向 stderr 输出内容。stderr是不带缓冲的
virtual UsageEnvironment& operator<<(char const* str);
virtual UsageEnvironment& operator<<(int i);
virtual UsageEnvironment& operator<<(unsigned u);
virtual UsageEnvironment& operator<<(double d);
virtual UsageEnvironment& operator<<(void* p); protected:
// 避免直接构造对象,只能通过createNew来创建
BasicUsageEnvironment(TaskScheduler& taskScheduler);
// called only by "createNew()" (or subclass constructors)
virtual ~BasicUsageEnvironment();
};

BasicUsageEnvironment的构造与析构

注意构造和析构是protected权限的。在创建对象的时候只能使用createNew方法。

BasicUsageEnvironment的构造函数还是调用了其基类BasicUsageEnvironment0的带参构造,要注意的是在BasicUsageEnvironment0的构造中又调用了UsageEnvironment的带参构造。如果是win32平台,其调用了initializeWinsockIfNecessary进行来初始化WinSOCK,之后才可以正常使用WinSOCK相关API。如果不是windows平台就不需要这么麻烦了,windows网络编程是一件麻烦事。

initializeWinsockIfNecessary函数定义在live555sourcecontrol\groupsock\inet.c文件中。注意C++中对C函数不能直接调用,要先使用extern “C”来声明。原因是C和C++编译器对函数名的处理不一致。

#if defined(__WIN32__) || defined(_WIN32)
extern "C" int initializeWinsockIfNecessary();
#endif BasicUsageEnvironment::BasicUsageEnvironment(TaskScheduler& taskScheduler)
: BasicUsageEnvironment0(taskScheduler) {
#if defined(__WIN32__) || defined(_WIN32)
if (!initializeWinsockIfNecessary()) {
setResultErrMsg("Failed to initialize 'winsock': ");
reportBackgroundError();
internalError();
}
#endif
}

BasicUsageEnvironment的析构还是什么也没有做,但是要注意的是,对象析构的时候会调用基类的析构函数

顺带再多说一点C++对象的构造析构过程。C++类定义中,构造函数不能使用virtual修饰,而析构函数请尽量使用virtual修饰。为什么呢?因为将析构函数加入虚函数表可以使得对象在析构的时候可以正确调用对应的析构函数,避免内存泄露等问题。在构建对象的时候,构造函数的调用顺序是 基类的构造—》派生类的构造,析构顺序与之相反,是 派生类的析构—》基类的析构

BasicUsageEnvironment::~BasicUsageEnvironment() {
}

createNew方法(创建对象)

在堆上(heap)动态创建一个BasicUsageEnvironment对象并返回对象地址。这是一个静态方法。

BasicUsageEnvironment*
BasicUsageEnvironment::createNew(TaskScheduler& taskScheduler) {
return new BasicUsageEnvironment(taskScheduler);
}

getErrno方法

这个方法在BasicUsageEnvironment0中实现setResultErrMsg的时候用到了。其返回一个错误码,在windows相关平台是上一次发生网络错误的错误代码,其他平台是全局的errno。考虑一下errno的线程安全性。

int BasicUsageEnvironment::getErrno() const {
#if defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_WCE)
return WSAGetLastError();
/* #include <winsock.h>
int PASCAL FAR WSAGetLastError ( void );
注释:该函数返回上次发生的网络错误.当一特定的Windows Sockets API函数指出一个错误已经发生,
该函数就应调用来获得对应的错误代码.
返回值:返回值指出了该线程进行的上一次Windows Sockets API函数调用时的错误代码.
*/
#else
return errno;
#endif
}

operator<<方法(输出到strerr)

这几个方法就不说了,还是调用的C的库函数fprintf输出参数内容到stderr。其实这里可以使用C++面向对象的方法来解决。C++标准库中定义了std::cerr对象用于将数据发生到标准错误流,其用法和std::cout可谓是如出一辙。这里重载后使用方法也和std::cout及其类似,观察其返回值便知了。

UsageEnvironment& BasicUsageEnvironment::operator<<(char const* str) {
if (str == NULL) str = "(NULL)"; // sanity check
fprintf(stderr, "%s", str);
return *this;
}
UsageEnvironment& BasicUsageEnvironment::operator<<(int i) {
fprintf(stderr, "%d", i);
return *this;
}
UsageEnvironment& BasicUsageEnvironment::operator<<(unsigned u) {
fprintf(stderr, "%u", u);
return *this;
}
UsageEnvironment& BasicUsageEnvironment::operator<<(double d) {
fprintf(stderr, "%f", d);
return *this;
}

cpp UsageEnvironment& BasicUsageEnvironment::operator<<(void* p) { fprintf(stderr, "%p", p); return *this; }

26 BasicUsageEnvironment基本使用环境——Live555源码阅读(三)UsageEnvironment的更多相关文章

  1. 25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment

    25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment 25 BasicUsageEnvironment0基本使用环境基类— ...

  2. 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment

    24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类——Live555源码阅读 ...

  3. 23 使用环境 UsageEnvironment——Live555源码阅读

    23 使用环境 UsageEnvironment——Live555源码阅读(三)UsageEnvironment 23 使用环境 UsageEnvironment——Live555源码阅读(三)Usa ...

  4. 27 GroupSock概述(一)——live555源码阅读(四)网络

    27 GroupSock概述(一)——live555源码阅读(四)网络 27 GroupSock概述(一)——live555源码阅读(四)网络 简介 1.网络通用数据类型定义 2.Tunnel隧道封装 ...

  5. 11 AlarmHandler定时处理类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  6. 8 延时队列相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  7. 4 Handler相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. Handler相关类概述 处理程序相关类一共有三个,其没有派生继承关系,但是其有友元关系和使用关系 ...

  8. TimeVal类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 这里是时间相关类的第一个部分. TimeVal类 TimeVal类定义在live555source ...

  9. 40 网络相关函数(八)——live555源码阅读(四)网络

    40 网络相关函数(八)——live555源码阅读(四)网络 40 网络相关函数(八)——live555源码阅读(四)网络 简介 15)writeSocket向套接口写数据 TTL的概念 函数send ...

随机推荐

  1. 自然语言18.1_Named Entity Recognition with NLTK

    QQ:231469242 欢迎nltk爱好者交流 https://www.pythonprogramming.net/named-entity-recognition-nltk-tutorial/?c ...

  2. fileinput模块

    刚才练习的时候,报如下错误: AttributeError: module 'fileinput' has no attribute 'input',后来Google参考这篇文章https://mai ...

  3. 分享jquery实现百叶窗特效的图片轮播

    首先非常感谢网友嘉翼的无私分享,这是他刚在网站扣下来的特效,第一时间与大家分享,jquery实现百叶窗特效的图片轮播 使用方法: 1.引用css文件,css文件里面已经做了注释,基本只需要修改宽高就好 ...

  4. Python之路【第十一篇续】前端之CSS补充

    CSS续 1.标签选择器 为类型标签设置样式例如:<div>.<a>.等标签设置一个样式,代码如下: <style> /*标签选择器,如果启用标签选择器所有指定的标 ...

  5. 命名不规范引发的DropDownListFor无法选中

    问题的引出: 项目中遇到和以下链接相同的问题,大概可以描述为:后台ViewData["KeyName"],前台Model属性里也有一个字段KeyName,那么DropDownLis ...

  6. 使用Struts 2框架实现文件下载

    从服务器发送一个文件到浏览器需要以下几个步骤 把HTTP响应里的ContentType标头设置为被下载文件的内容类型.ContentType标头的作用是表明数据包里的数据是什么类型, 它由一个多媒体类 ...

  7. Hibernate uniqueResult方法的使用

    以前写代码,总免不了编写登陆部分.在获取user的时候,只可能返回一个user实例,或者为null.以前使用以下方法实现.public User get(String id){      Sessio ...

  8. 在虚机中安装CentOS

    摘要 最近看到.net core 1发布的内容,也想尝试着在lunix上跑一圈.linux这方面的知识一直都没怎么接触过,只在工作中见同事操作过,看到满屏幕的命令行,感觉非常的高大上,趁着现在赶紧学习 ...

  9. hdu4950 Monster (水题)

    4950 Monster Monster Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...

  10. hdu4888 Redraw Beautiful Drawings 最大流+判环

    hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/6553 ...