做梦诗人的博客

仰天大笑出门去


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

  • 搜索
关闭

C++ 智能指针

发表于 2021-09-12   |   分类于 C/C++

导语
本篇不对智能指针的实现原理做详细研究,只讨论为什么要使用智能指针,以及使用规范和注意事项。

关于指针和智能指针

指针是一个变量,存储一块内存区域的地址。
指针指向一块内存,通过该指针可随意修改或者删除其中内容,那么我们可以说这个指针对这块内存具有所有权(ownership) 。

PS:通常说的指向一个对象的指针,严格意义上来说应该是指向一个对象所在内存的指针。指针可以说和对象本身是没关系的,只是对象的类型(class)更详细的描述这块内存区域存的是什么内容。

指针存在的意义:
1.访问特定内存中的数据
2.管理所拥有的内存,不再使用的内存要及时通知系统释放

裸指针能满足以上的访问和管理内存的需求,但是存在缺陷:
多个指针可以指向同一块内存
也就是意味着权限混乱,比如创建(new)多个指针指向同一块内存,但是每个指针使用完毕,都没有释放(delete),从而导致内存泄露。
或者所有的指针只要自己使用完毕就去释放内存,势必会造成正在使用该内存的地方产生未知结果,或者重复释放(delete)同一块内存导致崩溃。

阅读全文 »

宏 Macro

发表于 2021-09-05   |   分类于 C/C++

导语
本篇是关于宏定义的一些知识总结

1. 预处理 preprocess

根据程序中的预处理指令,预处理器把宏名替换成其表示的内容–宏展开(macro expansion);
预处理器指令从#开始运行,到后面的第1个换行符为止(指用Enter按下的换行,而不是 \n)。即:指令的长度仅限于一行;
在预处理开始前,编译器会把多行物理行(physical line)处理为一行逻辑行(logical line)。即:找到反斜杠\后面的换行符,把反斜杠和换行符删掉
双引号字符串中的文本不会被宏替换!

阅读全文 »

Working with git and ssh

发表于 2021-08-29   |   分类于 git

导语
从2021年8月14日之后,使用git对github进行身份验证操作的时候不再接受使用账号密码形式clone和push代码,必须使用acces_token或者基于SSH 的方式了。本文记录SSH 的使用过程。

一、生成shh密钥

进入 .ssh 目录,windows下一般在默认用户文件夹下 Users/Administrator/.ssh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cd C:\Users\Administrator\.ssh

ssh -V # 查看版本号,确认是否安装ssh

ssh-keygen -t rsa -C "email@abc.com" # 生成ssh密钥

Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/Administrator/.ssh/id_rsa): id_rsa_pubrepo # 此处输入密钥的名称,方便后面管理多个密钥
Enter passphrase (empty for no passphrase):# 回车
Enter same passphrase again:# 回车
Your identification has been saved in id_rsa_pubrepo.
Your public key has been saved in id_rsa_pubrepo.pub.
The key fingerprint is:
SHA256:xxxxxxxxxxxxx email@abc.com
The key's randomart image is:
+---[RSA 3072]----+
| . . . |
| o = oo. |
| . ..*+. . |
| . .o.B.* |
| . *.E=o |
| ..+*B= |
+----[SHA256]-----+
阅读全文 »

Garbage Collection in UE4

发表于 2021-08-23   |   分类于 UE4

导语
UE4 C++ 不同于原生的C++, UE内置了GC系统。对于有些人来说,GC帮我们处理了弃用的对象,防止了内存泄漏,确实是一件令人愉快的事情。然后有的时候,如果不了解GC规则,可能会给开发带来大麻烦。

什么对象会被GC 系统处理?

GC主要思想很简单——要让 GC系统 相信对象是多余的并删除它,必须满足以下几个条件:

  • 这个对象不再被UE 的反射系统引用。

  • 指向对象的指针没有被保存在容器中。

  • 对象在其作用域内没有被强指针指向,比如shared pointers, shared references, unique pointers

  • 创建对象的代码块经结束执行(离开作用域)

  • 对象没有添加到根节点 AddToRoot()

  • 对象必须是继承自Uobject

有一个要特殊注意的例外,我们可以显式地将UObject派生的类对象标记为销毁。

阅读全文 »

UE4 数据压缩方法(三)

发表于 2020-11-20   |   分类于 UE4

导语
之前我们压缩了整数(压缩方法一),Angle角度浮点数(压缩方法二),那么用来同步位置的FVector是否也可以压缩呢?
整数压缩部分是用编码解压实现的,属于无损压缩,Angle角度浮点数是用一个小范围的数据集来表示一个大范围的数据集,属于有损压缩。那么我们可能会问,如果同步的数据不一致,对于不同客户端的计算或者显示结果是否会有影响呢?比如一个游戏中,一个玩家在不同的客户端上的位置和方向存在较大的差异,那肯定是不行的。

实现思路

本次我的思路是对于特定情况下的一些数据压缩提供一种思路。比如我们的一个多人在线应用,用户的活动范围被限制在一定的范围内,也就是玩家的位置坐标的最大值能用更短的整数来存储。那么我们就有压缩的空间了。

阅读全文 »

UE4 数据压缩方法(二)

发表于 2020-11-20   |   分类于 UE4

导语
在之前的压缩方法一里面我们把表示状态的数据编码到uint32的每个bit上,进行网络传输后再解码出来,以达到压缩数据,节省带宽的效果。这次我们尝试把UE4中的Rotator数据也进行压缩。

实现思路

UE中的Rotator本质上就是一个结构体,其中有三个float,那么传输一个Rotator要占用12个字节。
但是可以发现Rotator就是表示三个轴的旋转角度,而角度的范围是0 - 360.0,远小于float可以表示的范围,那么我们的目标就变成了如何用更小的数据量来传递0 - 360.0 了。
根据压缩精度不同,本文提供2种压缩方法,均为有损压缩。

阅读全文 »

UE4 数据压缩方法(一)

发表于 2020-11-19   |   分类于 UE4

导语
对于一个多人实时在线系统,数据同步是关键环节,在相同的网络环境下,数据量决定了同时在线用户量体,数据量也会影响网络延迟和加载时间。所以承载数据的网络带宽是珍贵且昂贵的,所以要在网络数据同步环节细扣每一个 bit !

案例说明

一个用户有16个设备,每个设备有三种状态: 0 未连接,1 连接异常,2 连接正常。需要用最小的数据量来同步这16个设备的连接状态。

1
2
3
4
5
6
enum DeviceState
{
Connected,
Abnormal,
Normal
};

实现思路

每个 bit 有 0 和 1 两种状态,那么至少需要用2个 bit 来表示三种状态,16个设备需要32个 bit。
可以把这8个属性编码到一个 uint32 的整数中,前16位分别表示是否连接,后16位分别表示连接是否正常。

阅读全文 »

UE4 Config配置文件的使用

发表于 2020-11-17   |   分类于 UE4

导语
本篇文章将简单介绍UE4 项目开发过程中, 如何使用配置文件来修改项目中的参数
我们知道在UE4项目的根目录下都会有一个 Config 的文件夹,里面有各种.ini 结尾的文件,这里面都是UE4 默认生成的一些配置文件. 今天我们要做的就是使用自己定义的.ini 文件,定义自己的 Config 变量, 并用这些变量来初始化 Class 中的定义的成员变量.

版本:UE4.25

1.关于打包后Config文件的位置

如果采用Development 或者DebugGame 模式打包的话, Config 文件会生成在 打包目录\项目名称\Saved\Config\WindowsNoEditor 目录中, 但是如果用Shipping 模式打包的话, 会发现找不到这个目录了, 那么在Windows 系统下 我们可以在如下地址找到 C:\Users\用户名\AppData\Local\项目名称\Saved\Config\WindowsNoEditor.
接下来也会把我们自己的 Config 文件生成在指定的目录下,方便找到和修改.

2. 把成员变量设置为可用Config 配置

在UE4 c++ Class 变量的宏定义中, 加入 config 关键字

1
2
3
// 是否作为服务器启动
UPROPERTY(config ,Category="CustomIni")
bool bServer=false;

阅读全文 »

UE4 重复点击检测

发表于 2020-10-04   |   分类于 UE4 , UMG

导语
在开发过程中,我们经常会有这样的需求:限制用户的点击频率。一方面考虑到服务器数据请求的压力,一方面防止恶意攻击服务器。
我在网上也能看到其他的实现方法,有用Delay 节点的,有传递点击按钮对象的。总觉得使用起来不是很方便,因此打算自己实现一个,简单易用,没有任何使用代价的方式。自认为是最优雅的方式了。

版本:UE4.25

实现思路

本次针对的是UE4 蓝图UMG 系统,所以是在蓝图的基础上实现的,利用了系统的运行时间。
首先第一点击之后调用一个宏记录当前的系统运行时间,然后第二次点击再次调用该宏,比对当前时间和上次记录的时间的差值是否小于我们设定的点击间隔。以此来决定后面的代码要不要继续执行。

阅读全文 »

UE4 多线程FRunnable(一)

发表于 2019-11-04   |   分类于 UE4 , 多线程

导语
在开发过程中,有时候会遇到需要使用线程相关逻辑,比如网络相关,动态加载资源的,希望不要影响主线程的运行。
版本:UE4.25

UE4遵循C++11的标准,但是他并没有使用std::thread,而是自己实现了一套多线程机制。

在UE4里面创建多线程的三种方式,我们会分三篇来分析和使用:

  1. 继承FRunnable接口创建一个线程任务,适用于复杂运算
  2. 直接创建AsyncTask来调用线程池里面空闲的线程
  3. 通过TaskGraph系统来异步完成一些自定义任务

这三种方式本质相同,但是用法不同。

本篇尝试使用FRunnable。

案例说明

给定一个txt文件路径数组,通过异步的方式读取文件,并且返回文件的内容数组。

FRunnable分析

FRunnable 是线程的执行体,提供相应的接口。FRunnable需要依附与一个FRunnableThread对象,才能被执行,

真正的线程其实是FRunnableThread,不同平台的线程都继承自他,如FRunnableThreadWin,里面会调用Windows平台的创建线程的API接口。

阅读全文 »
123
Dreamingpoet

Dreamingpoet

靡不有初 鲜克有终

26 日志
15 分类
45 标签
RSS
Github
Creative Commons
链接
  • 建站日志
© 2016 - 2023 Dreamingpoet
由 Hexo 生成
主题 - NexT.Pisces