26 BasicUsageEnvironment基本使用环境——Live555源码阅读(三)UsageEnvironment
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的更多相关文章
- 25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment
25 BasicUsageEnvironment0基本使用环境基类——Live555源码阅读(三)UsageEnvironment 25 BasicUsageEnvironment0基本使用环境基类— ...
- 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment
24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类——Live555源码阅读 ...
- 23 使用环境 UsageEnvironment——Live555源码阅读
23 使用环境 UsageEnvironment——Live555源码阅读(三)UsageEnvironment 23 使用环境 UsageEnvironment——Live555源码阅读(三)Usa ...
- 27 GroupSock概述(一)——live555源码阅读(四)网络
27 GroupSock概述(一)——live555源码阅读(四)网络 27 GroupSock概述(一)——live555源码阅读(四)网络 简介 1.网络通用数据类型定义 2.Tunnel隧道封装 ...
- 11 AlarmHandler定时处理类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- 8 延时队列相关类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- 4 Handler相关类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. Handler相关类概述 处理程序相关类一共有三个,其没有派生继承关系,但是其有友元关系和使用关系 ...
- TimeVal类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 这里是时间相关类的第一个部分. TimeVal类 TimeVal类定义在live555source ...
- 40 网络相关函数(八)——live555源码阅读(四)网络
40 网络相关函数(八)——live555源码阅读(四)网络 40 网络相关函数(八)——live555源码阅读(四)网络 简介 15)writeSocket向套接口写数据 TTL的概念 函数send ...
随机推荐
- 图片延迟加载jquery插件imgLazyLoading
实现了图片延迟加载功能,插件代码非常简洁,且每个功能都把注释写得非常详细,适合网友们学习,好好利用哦 引入图片延迟加载Jquery插件文件后,页面使用代码如下: <script type=&qu ...
- 跟我一起玩转Sencha Touch 移动 WebApp 开发(一)
1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 自定义图标的方式 WebApp产品测试和发布 HTML5离线缓存 发布 ...
- guid正则表达
a-fA-F0-9 加上下划线 _ 可以用 \w 来代替. ^\w{8}-(\w{4}-){3}\w{12}$ 如果不可以用下划线, 0-9 用 \d 代替 a-fA-F 就用其中一个 a-f,然后匹 ...
- Crontab的格式
第1列分钟1-59第2列小时1-23(0表示子夜)第3列日1-31第4列月1-12第5列星期0-6(0表示星期天)第6列要运行的命令 下面是crontab的格式:分 时 日 月 星期 要运行的命令 这 ...
- MySQL数据导出与导入
工具 mysql mysqldump 应用举例 导出 导出全库备份到本地的目录 mysqldump -u$USER -p$PASSWD -h127.0.0.1 -P3306 --routines -- ...
- Python之路【第六篇】:面向对象编程相关
判断类与对象关系 isinstance(obj, cls) 判断对象obj是否是由cls类创建的 #!/usr/bin/env python #-*- coding:utf-8 -*- class ...
- Pycharm 使用
Pycharm基本使用http://edu.51cto.com/index.php?do=lession&id=118722 Pycharm的基本使用 在Pycharm下为你的Python ...
- lishell学习之路:流程控制(case)
流程控制case语句: 介绍:多分支case条件语句 1.case语句和if..elif..else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而i ...
- [译]了解AngularJS $resource
原文: https://learnable.com/books/angularjs-novice-to-ninja/preview/understanding-angularjs-resource-e ...
- Linux 中常见的命令行,持续更新
1.添加自己的环境变量 root@adonis:~# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin r ...