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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理