Future 聊天室功能账号管理
实现登录、注册、注销
实现找回密码(提高)
好友管理
实现好友的添加、删除、查询操作
实现显示好友在线状态
禁止不存在好友关系的用户间的私聊
实现屏蔽好友消息
实现好友间聊天
群管理
实现群组的创建、解散
实现用户申请加入群组
实现用户查看已加入的群组
实现群组成员退出已加入的群组
实现群组成员查看群组成员列表
实现群主对群组管理员的添加和删除
实现群组管理员批准用户加入群组
实现群组管理员/群主从群组中移除用户
实现群组内聊天功能
聊天功能
实现查看历史消息记录
实现用户间在线聊天
实现在线用户对离线用户发送消息,离线用户上线后获得通知
实现在线发送文件
实现在线用户对离线用户发送文件,离线用户上线后获得通知/接收
实现后台发送文件
实现用户在线时,消息的实时通知
收到好友请求
收到私聊
收到加群申请
其他
使用 C++编程语言
使用 I/O 多路复用完成本项目
C++:Epoll ET 模式
使用数据库完成数据存储
Redis 和 mysql
历史消息采用redis做告诉缓存,mysql来存储大量...
强制类型转换C++提供了四个强制类型转换的关键字:
static_cast
const_cast
reinterpret_cast
``dynamic_cast`
static_cast1static_cast<目标类型>(表达式)
12int num = 2;double result =static_cast<double>(num);
该运算符将表达式转换为目标类型。但没有进行运行时类型检查来保证转换的安全性。
主要用法
用于类层次结构中父类和子类之间指针或引用的转换.进行上行转换是安全的(即将子类的指针或引用转换成父类是正确的);进行下行转换的时候,由于没有动态类型检查,所以是不安全的。继承必须为public
用于基本类型之间的转换,如int与char,安全性也需要程序员来保证
把空指针转换为目标类型的空指针
1234567891011121314151617181920212223242526272829class Person{public: void print() { ...
Lambda表达式匿名函数是很多高级语言都支持的概念,如lisp语言在1958年首先采用匿名函数。匿名函数有函数体,但没有函数名。C++11中引入了lambda表达式。利用lambda表达式可以编写内嵌的匿名函数,用以替换独立函数或者函数对象,并且使代码更可读。但是从本质上来讲,lambda表达式只是一种语法糖,因为所有其能完成的工作都可以用其它稍微复杂的代码来实现。但是它简便的语法却给C++带来了深远的影响。如果从广义上说,lamdba表达式产生的是函数对象。
相同类似功能我们也可以使用函数对象或者函数指针实现:函数对象能维护状态,但语法开销大,而函数指针语法开销小,却没法保存范围内的状态。lambda表达式正是结合了两者的优点。
声明Lambda表达式1234567// 完整语法[capture list] (params list) mutable(optional) constexpr(optional)(c++17) exception attribute -> return type { function body };// 可选的简化...
可变参数模板可变参数模板是C++11引入的一个特性,它允许定义一个接受任意数量参数的模板.
在函数模板或类模板中,我们可以使用可变参数模板来定义接受任意数量参数的函数或类。可变参数模板使用了模板参数包(template parameter pack),它允许我们将零个或多个模板参数打包成一个参数集合。
123456789template <typename T>T sum(T arg){ return arg;}template<typename T,typename...Args>T sum(T first ,Args...res){ return first+sum(rest...);}
尾部类型推导当需要使用尾部类型推导的时候,通常是因为函数的返回类型依赖于函数参数或其他的上下文.
123456789101112auto add=[](int x,int y)->int { return x+y;}auto add=[](int x,int y)->auto&...
C++11线程特性std::thread标准库
C++11引入了std::thread来创建线程,支持对线程join或者detach.
12345678910111213141516171819202122232425262728#include <iostream>#include <thread>using namespace std;int main() { auto func = []() { for (int i = 0; i < 10; ++i) { cout << i << " "; } cout << endl; }; std::thread t(func); if (t.joinable()) { t.detach(); } auto func1 = [](int k) { ...
shell主函数
先创建一个Shell类型的类
然后屏蔽信号ctrl+c与ctrl+D
接着打印提示符,接收命令的输入
判断该次命令是否含有exit clear !等信息,如果有,执行相应操作
通过调用解析函数解析本次输入的命令
屏蔽信号
ctrl + C
1signal(SIGINT, SIG_IGN);//将该信号的处理方式设置为忽略
ctrl + D
1234struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_cc[VEOF] = _POSIX_VDISABLE; tcsetattr(STDIN_FILENO, TCSANOW, &term);
首先定义一个termios类型的结构体,用来存储终端相关的属性信息
然后通过调用tcgetattr函数将获取终端的相关属性,并将这些属性保存到 **term **结构体中,第一个参数表示标准输入,是一个预定的文件描述符常量
将结构体中的c_cc数组成员的VEOF设置为禁用. c_cc数组是包含终端特殊字符的数组,VEOF是...
利用条件表达式完成下面的命题:学习成绩成绩>=90分的同学用A表示,学习成绩在60~89分的同学用B表示哦=,学习成绩在60分以下的同学用C表示.int gra=0;
classclass 是一种用于创建用户定义的数据类型的关键字。它是面向对象编程(OOP)的基本概念之一。通过使用 class,您可以将数据成员(属性)和成员函数(方法)封装在一个单一的实体中,从而使代码更有组织性和可维护性。
语法: class 类名 {访问权限 : 属性\行为};
class 的功能与struct类似,但提供了更为丰富的功能.
class 可以在设计的时,可以把属性和行为放在不同的权限下,加以控制.
权限的分类:
public 公共权限
protected 保护权限
private 私有权限
12345678910111213141516171819202122232425262728//公共权限 public//保护权限 protected//私有权限 private//私有权限与保护权限在类内可以访问,在类外不可以访问clas...
生成个人访问令牌
生成secrets前首先要生成个人访问令牌
创建令牌
验证您的电子邮件地址(尚未验证)
在任何界面的右上角,点击个人资料照片,点击设置
在左边侧边栏中,点击Developer settings(在最下边)
然后在Personal access tokens的Tokens中选择Generate new tokens然后选择第二个
选则您要授予此令牌的范围或权限。要使用令牌从命令行访问存储库,请选择repo。如果还需要其他权限请自行勾选。(workflow也进行选择),然后确定即可
最后
将令牌复制到剪切板。出于安全的原因,在您离开该界面后,您将无法再次看到该令牌。
配置github项目的secrets在github的仓库中打开设置。
在侧边栏中点击Secrets and variables中的Actions。
点击New repository secret。
名称是随便起得。Secret就是刚才生成的令牌.
详细教程
更改该仓库的写权限在该仓库侧边栏中选择Actions当中的General,在该页面下的Workflow当中选择第一个并前保存.
详细教程
设...
myls
ls 是一个常用的命令行工具,用于列出指定目录中的文件和子目录。ls 的基本语法是:
1ls [选项] [文件或目录]
以下是一些常用的 ls 命令选项:
-l:以长格式显示文件信息,包括文件类型、权限、所有者、组、大小、修改时间等。
1ls -l
-a:显示所有文件,包括隐藏文件(以点开头的文件)。
1ls -a
-r:与 -l 逆序输出文件信息。
1ls -r
-R:递归显示子目录中的文件。
1ls -R
-t:按修改时间排序,最新修改的文件显示在前面。
1ls -lt
-S:按文件大小排序,最大的文件显示在前面。
1ls -lS
-i:显示文件的 inode 号码。
1ls -i
思路1.-i -a -R -r -i -s -l为命令行参数,我们首先需要解析命令行参数。
2.我们需要对以上参数进行了解,并进行构思一个框架以便后续对代码的维护与可读性。
3.我觉得可以将以上参数分为三类:1.-a 为确定需要显示的文件多少,例如-a包含 . 隐藏文件。2.-s -t 排序参数,如果含有该参数,则就需要对文件显示进行排序。3.-i -l 为输出参数,...
malloc&freemalloc(0)返回一个有效的空间长度为0的内存首地址,但是没法用(只能进行申请和释放).
动态申请数组指针:
12int (*P)[3]=(int(*)[3])=malloc(sizeof(int)*3);int (*q)[2][3]=(int(*)[2][3])malloc(sizeof(int)*6);
初始化:
malloc函数分配得到的内存是未初始化的.一般在使用该内存空间时,要调用memset来初始化为0.
1void* memset(void *dest,int c,size_t count);
该函数可以将指定的内存空间按字节单位置为指定的字符c。其中,dest为要清零的内存空间的首地址,c为要设定的值,count为被操作的内存空间的字节长度。
1void* memcpy(void* dest, void* src, size_t count);
此函数也是按照字节进行拷贝的,dest指向目标地址的指针,也就是要被赋值的空间首地址;src指向源地址的指针,也就是要被复制的空间的首地址;count跟memset()一样表示被拷...