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. cannot start session without errors

    访问phpmyadmin出现如标题错误,解决方案如下: cd /var/lib/php 更改目录权限chown nginx:nginx -R session/ That's All!

  2. EasyDarwin

     1.EasyDarwin多媒体点播实现 新版本EasyDarwin都加入了中心管理服务EasyCMS, 对于点播系统,EasyCMS不是必须的. MP4点播,需要将mp4文件hint之后才行,MP4 ...

  3. Mount挂载命令使用方法

    语法: mount -t 类型 -o 挂接方式 源路径 目标路径     -t 详细选项: 光盘或光盘镜像:iso9660 DOS fat16文件系统:msdos Windows 9x fat32文件 ...

  4. [c#]RabbitMQ的简单使用

    摘要 Message Queue消息队列,简称MQ,是一种应用程序对应用程序的通信方法,应用程序通过读写出入队列的消息来通信,而无需专用连接来链接它们.消息传递指的是程序之间通过在消息中发送数据进行通 ...

  5. linux 下tar 的用法

    1)tar -r 可以append file to tared_package.tar -rf tared_package 添加文件2)不打包目录用ls -a --color=none | grep ...

  6. motto2

    Baby you've done enough that cut your breath.Don't beat yourself up don't need to turn so fast.Somet ...

  7. Nosql 之 Redis(可做缓存 )

    下载 可以下载解压安装的 地址:https://github.com/dmajkic/redis/downloads 修改 redis.conf 取消注释 requirepass foobared运行 ...

  8. div+css使多行文字垂直居中?

    1.单行文字: 设置height = line-height; 多行文字: 设置 padding, 自己要计算一下? vertical-align: 可以设置垂直居中, 但是只是针对本身就具有 ali ...

  9. BufferedReader readLine()方法

    控制台输入字符串之后回车,后台接收传来的字符串,代码如下: import java.io.BufferedReader; import java.io.IOException; import java ...

  10. ImageView.ScaleType8种用法

    1·ImageView.ScaleType.center:图片位于视图中间,但不执行缩放. 2·ImageView.ScaleType.CENTER_CROP 按统一比例缩放图片(保持图片的尺寸比例) ...