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 ...
随机推荐
- ctypes 操作 python 与 c++ dll 互传结构体指针
CMakeLists.txt # project(工程名) project(blog-3123958139-1) # add_library(链接库名称 SHARED 链接库代码) add_libra ...
- ES6 import export
import import './module1.js'; (无对象导入) import d from './module1.js'; (导入默认对象) import {Employee, getEm ...
- 让Xcode的控制台支持LLDB类型的打印
这个技巧个人认为非常有用 当Xcode在断点调试的时候,在控制台中输入 po self.view.frame 类似这样的命令会挂掉,不信可以亲自去试试(Xcode7 以后支持LLDB类型的打印) 那么 ...
- web.config中customErrors与httpErrors的区别
打开IIS,我们发现会有两个处理错误页的地方,见下图: 进行不同的设置之后,我们发现设定结果会反应在web.config: .NET Error Pages设定被写入system.web/custom ...
- android控件库(1)-带删除功能的EditText
DJEditText.java /** * Created by xp.chen on 2016/11/25. */ public class DJEditText extends AppCompat ...
- 看见了就转来了, 涉及到UBOOT 地址的一个问题.
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);什么意思? 这是UBOOT 中的一个分配视频帧缓冲区地址的函数,我想问的是:加一个 ...
- Python画图笔记
matplotlib的官方网址:http://matplotlib.org/ 问题 Python Matplotlib画图,在坐标轴.标题显示这五个字符 ⊥ + - ⊺ ⨁,并且保存后也能显示 h ...
- JDBC:从数据库中取数据的一个bug
先看错误信息: java.sql.SQLException: Before start of result set at com.mysql.jdbc.SQLError.createSQLExcept ...
- Sphinx扩展安装安装
Coreseek官方教程中建议php使用直接include一个php文件进行操作,事实上php有独立的sphinx模块可以直接操作coreseek(coreseek就是sphinx!)已经进入了php ...
- sql中的常见的全局变量
select APP_NAME ( ) as w --当前会话的应用程序 select @@IDENTITY --返回最后插入的标识值 select USER_NAME() --返回用户数据库用户名 ...