十一假期后就有点懒散,好长时间都没想起来写东西了。另外最近在打LOL的S赛。接触LOL时间不长,虽然平时玩的比较少,水平也相当菜,但是像这种大型的赛事有时间还是不会错过的。主要能够感受到选手们对竞技的激情,对瞬息万变的战局的应变,非常精彩。KeKe~~。

这一篇主要对UVW的源码讨论来收个尾,就介绍一下项目中其他的一些好玩的东西,稍微丰富一下知识。

1、模版

之前说了很多东西,但是都把它给忽略了,对于C++的模版,很多人对此有看法,说它难以理解,编写困难等等。

我们都知道,模版也是C++多态的一种,属于编译期多态,也就是说C++把很多运行期的工作加到编译期了,你的代码保持了在语言层面的抽象层次。然而实际上编译器在编译时却对同类型模版的使用进行了特化。所以相比较运行时的多态,模版的运行性能是更好的,但是编译的时间可能就稍长了一些。

虽然那些对模版的看法都讲的过去,但是模版在应用中所带来的作用是相当大的。举一个最简单的例子:

std::shared_ptr<uvw::TcpHandle> tcp = loop.resource<uvw::TcpHandle>();

这是我们项目中一个创建TcpHandle的语句,如果我们按照一般C的思路,写出来的代码很可能是这样的:

TcpHandle* tcp = loop.resource(type);

OK,看上去很正常,但是暴露了很多问题,这个resource函数的原型应该是:

void* loop::resource(int type); 或者 Handle* loop::resource(int type);

它肯定是返回void*或者Handle这个基类的指针,但是你只能通过你对代码的理解和type的值来判定,它返回的是TcpHandle*类型。万一我不小心把返回类型写成了UdpHandle*,它同样继承自Handle类,C++是没有对此的检测的。那这时候模版的价值就显示出来了,它可以直接根据模版的类型,对返回的类型起到限制作用。避免了上面情况的出现。

再比如我们在 第二篇 中讲static的时候,没有模版就不能实现那样的功能。

有些朋友在编码的时候很少或者根本就不用模版,顶多在用一些容器的时候。或许因为就算用模版,也会造成上面提到的一些负面影响。所以很多人知道模版,但是不常使用,不常使用的东西往往也会忘的非常快,造成这样一个不好的循环。如果模版可以解决切实的编码问题,大胆一点用就是了,不要怕用错,错了才能更好的用嘛!

2、enum 

enum就是枚举类型,但是C++11对enum有扩展。先看这段代码:

fs.hpp  55 ~ 69

enum class UVDirentTypeT: std::underlying_type_t<uv_dirent_type_t> {
UNKNOWN = UV_DIRENT_UNKNOWN,
FILE = UV_DIRENT_FILE,
。。。。。。
}; enum class UVCopyFileFlags: int {
EXCL = UV_FS_COPYFILE_EXCL
};

enum和enum class的区别,有下面几点:

1、如果在同一个头文件中,有下面的代码:

 enum HandleType{TCP,UDP,POLL,FS};
enum StreamType{TCP,UDP,POLL,FS};

这是编译不通过的,因为本身enum就相当于 #define 的一个集合,名字是不能一样的。但是用 enum class 来写,则是OK的,比如:

 enum class HandleType{TCP,UDP,POLL,FS};
enum class StreamType{TCP,UDP,POLL,FS};

但是使用的时候是需要加上作用域的。

2、我们都知道enum中的每个元素都是可以直接转为int型的(对于不同的编译器,可能类型不一样)。但是 enum class 是不可以的。比如:

 enum HandleType{TCP,UDP,POLL,FS};
enum class StreamType{TCP,UDP,POLL,FS}; int handleType = TCP;
int streanType = StreamType::TCP; //错误

第5行就会产生编译错误,enum很容易被隐式的转为int,在某种意义上,是enum的一种缺陷,所以enum class解决了这个问题.

另外enum class的元素是可以指定类型的,比如:

 enum smallenum: int16_t
{
a,
b,
c
}; enum class altitude: char
{
high='h',
low='l',
};

可以看到,这个 enum class中的 “class” 是可以省略的。那如果我有需求,要将enum class转为需要的类型怎么办?比如上面的两个例子,可以这样搞:

 smallenum s = smallenum::a;
int16_t i = static_cast<int16_t>(s); altitude e = altitude::high;
char c = static_cast<char>(e);

当然,在switch 。。。 case。。。语句中是可以直接用的。

最后

到这里源码中关于语法一类的、使用的一些技术和方法就介绍到这里。这些东西其实也不难,也许大家都知道,不知道的通过介绍也有一些了解了,主要是让大家在看源码的时候可以舒服点,排除一些障碍。

有些看官可能对项目中的代码的书写形式,使用方式等很多东西不是很习惯,但是我想说这应该就是现代C++的一个编码模式。你可能在一个项目中看不见一个指针,看不见一个强转,使用大量的模版,使用很多限制关键字,类实现和定义放在同一个文件,如同java一般,还有其他很多看不习惯的地方。但是当你熟悉了,明白了,习惯了,说不定效率就上升了。其实这些说到底还是要提升对C++的认知。

之后我会再找一些在比较好的项目来和大家分享,比如架构,算法等方面的。由于水平有限,博客中若有错误,烦请指正。

UVW源码漫谈(四)的更多相关文章

  1. UVW源码漫谈(三)

    咱们继续看uvw的源码,这次看的东西比较多,去除底层的一些东西,很多代码都是连贯的,耦合度也比较高了.主要包括下面几个文件的代码: underlying_type.hpp resource.hpp l ...

  2. UVW源码漫谈(番外篇)—— Emitter

    这两天天气凉了,苏州这边连续好几天都是淅淅沥沥的下着小雨,今天天气还稍微好点.前两天早上起来突然就感冒了,当天就用了一卷纸,好在年轻扛得住,第二天就跟没事人似的.在这里提醒大家一下,天气凉了,睡凉席的 ...

  3. UVW源码漫谈(二)

    前一篇发布出来之后,我看着阅读量还是挺多的,就是评论和给意见的一个都没有,或许各位看官就跟我一样,看帖子从不回复,只管看就行了.毕竟大家都有公务在身,没太多时间,可以理解.不过没关系,我是不是可以直接 ...

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

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

  5. 39 网络相关函数(七)——live555源码阅读(四)网络

    39 网络相关函数(七)——live555源码阅读(四)网络 39 网络相关函数(七)——live555源码阅读(四)网络 简介 14)readSocket从套接口读取数据 recv/recvfrom ...

  6. 38 网络相关函数(六)——live555源码阅读(四)网络

    38 网络相关函数(六)——live555源码阅读(四)网络 38 网络相关函数(六)——live555源码阅读(四)网络 简介 12)makeSocketNonBlocking和makeSocket ...

  7. 37 网络相关函数(五)——live555源码阅读(四)网络

    37 网络相关函数(五)——live555源码阅读(四)网络 37 网络相关函数(五)——live555源码阅读(四)网络 简介 10)MAKE_SOCKADDR_IN构建sockaddr_in结构体 ...

  8. 36 网络相关函数(四)——live555源码阅读(四)网络

    36 网络相关函数(四)——live555源码阅读(四)网络 36 网络相关函数(四)——live555源码阅读(四)网络 简介 7)createSocket创建socket方法 8)closeSoc ...

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

    35 网络相关函数(三)——live555源码阅读(四)网络 35 网络相关函数(三)——live555源码阅读(四)网络 简介 5)NoReuse不重用地址类 6)initializeWinsock ...

随机推荐

  1. 201521123002《Java程序设计》第11周学习总结

    作业参考文件 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5 ...

  2. What is uClinux?

    What is uClinux? The original uClinux was a derivative of Linux 2.0 kernel intended for microcontrol ...

  3. python面向对象之封装

    一.封装 优点:(1)将变化隔离          (2)封装使用         (3)提高复用性        (4)提高安全性 封装原则:(1)将不需要对外提供的内容都隐藏起来         ...

  4. [06] Java的数据类型

    1.基本数据类型 1.1 基本数据类型 byte.chart.short.int.long.float.double.boolean 共8种数据类型为基本数据类型: 数据类型     位数     取 ...

  5. Spring - BeanPostProcessor接口(后处理器)讲解

    概述: BeanPostProcessor接口是众多Spring提供给开发者的bean生命周期内自定义逻辑拓展接口中的一个,其他还有类似InitializingBean,DisposableBean, ...

  6. editplus的设置

    1, 下载editplus3软件并且进行安装, 我这里是 EditPlus_3.4.1.1123_XiaZaiBa 2, 进行相关设置: 工具-->参数设置-->常规--勾选 (把Edit ...

  7. UEditor1.4.3.3整合Spring MVC和七牛

    [前言] 项目中涉及将UEditor上传服务器整合进已有的基于Spring MVC的服务中,并且将上传到本地改为上传到七牛,看似简单的一个需求,实际做起来还是遇到了一些困难.在这里分享一下经验-- 七 ...

  8. 关于ng-options

    在实际使用过程中对angular的ng-options指令有点不解,有的时候觉得很容易理解和上手,但其实等到遇到问题时,发现它很是生疏,(key,value)键值对获取,as关键词,track by ...

  9. 《MATLAB从入门到放弃》二维曲线和图形绘制基础(一): 什么是图形对象和句柄 ?

    图形对象 一个图形包含了不同的对象 图形包括 核心对象和绘制对象 .  核心对象 线条对象 : line 文本对象 : text 矩形对象 : rectangle 补丁对象 : patch 图像对象  ...

  10. 如何从两个List中筛选出相同的值

    问题 现有社保卡和身份证若干,想要匹配筛选出一一对应的社保卡和身份证. 转换为List socialList,和List idList,从二者中找出匹配的社保卡. 模型 创建社保卡类 /** * @a ...