C++
zyddst1314
奔跑的脚步不要停
展开
-
shell之“>/dev/null 2>&1” 详解
shell脚本语法原创 2022-11-18 17:26:37 · 529 阅读 · 1 评论 -
7.1---客户端与服务端的粘包现象演示(网络缓冲区)
客户端代码和服务端代码都使用前面文章所封装的class本文先对缓冲区做各种测试,文章最后会介绍粘包现象。接下来的几篇文章中会介绍客户端与服务端如何处理这种粘包现象一、测试1:循环发送与接收少量数据(8kb)测试1的过程为:服务端:服务端代码基本不变,其接收客户端发送过来的数据,在收到数据之后将相应数据回送给客户端客户端:客户端使用while()循环一直向服务端发送程序客户端与服务端的每次交互的单个数据包比较小,只有8字节//服务端代码如下#include "EasyTcpServer.hpp原创 2021-07-01 19:45:32 · 261 阅读 · 0 评论 -
6.1---将客户端封装为class
一、概述在前面的文章中,客户端的代码都是以面向过程的形式展现,本文将之前客户端的代码封装为一个class二、代码如下MessageHeader.hpp这个头文件包含所有的数据包的格式定义#ifndef _MessageHeader_hpp_#define _MessageHeader_hpp_ enum CMD{ CMD_LOGIN, CMD_LOGIN_RESULT, CMD_LOGOUT, CMD_LOGOUT_RESULT, CMD_NEW_USER_JOIN, CMD_原创 2021-07-01 19:40:09 · 114 阅读 · 0 评论 -
6.2---将服务端端封装为class
一、概述在前面的文章中,服务端的代码都是以面向过程的形式展现,本文将之前服务端的代码封装为一个class二、代码如下MessageHeader.hpp这个头文件包含所有的数据包的格式定义#ifndef _MessageHeader_hpp_#define _MessageHeader_hpp_ //消息的类型enum CMD{ CMD_LOGIN, //登录 CMD_LOGIN_RESULT, //登录结果 CMD_LOGOUT, //退出 CMD原创 2021-07-01 19:37:59 · 123 阅读 · 0 评论 -
5.2---将服务端代码进行跨平台移植(Windows、Unix)
一、跨平台移植概述前面的文章我们的代码都是在Windows下进行编译运行的,现在我们需要将代码移动到Linux和Mac OS操作系统上进行运行因为Linux和Mac OS底层都是使用Unix内核,因此将代码修改之后,在Linux和Mac OS上面都可以进行编译并运行,不需要单独设计两份二、代码修订代码修订1头文件修订:Windows与Unix下套接字使用的头文件不同,因此需要修订一些常量定义:Windows下有SOCKET、、INVALID_SOCKET、SOCKET_ERROR等宏的定义,但是原创 2021-07-01 19:35:49 · 441 阅读 · 0 评论 -
5.1---将客户端代码进行跨平台移植(Windows、Unix)
一、跨平台移植概述前面的文章我们的代码都是在Windows下进行编译运行的,现在我们修改代码,使其在Windows、Ubuntu、Mac OS系统上都可以运行因为Linux和Mac OS底层都是使用Unix内核,因此将代码修改之后,在Linux和Mac OS上面都可以进行编译并运行,不需要单独设计两份二、代码修订代码修订1头文件修订:Windows与Unix下套接字使用的头文件不同,因此需要修订一些常量定义:Windows下有SOCKET、、INVALID_SOCKET、SOCKET_ERROR原创 2021-07-01 19:29:17 · 551 阅读 · 0 评论 -
4---为客户端添加输入线程
一、为客户端添加输入线程在前一篇文章中我们的客户端不能手动的在命令行中输入命令发送给服务端,而是简单地书写了一小段代码,然后发送给服务端此处我们为客户端添加一个线程,此处采用的是C++11中的线程对象std::thread二、代码设计思路设计了一个全局变量g_bRun代表当前客户端正在运行,main函数主循环while中使用g_bRun在主循环while之前设计创建一个C++11线程对象,线程运行函数名为cmdThread(),函数参数为客户端的socket。并且该线程分离出了主线程(为什么要分离原创 2021-07-01 19:23:01 · 139 阅读 · 0 评论 -
3---将服务端、客户端升级为select模型
一、Windows下的selectWindows下的select函数与Unix下的select函数语法相同,但是有些语言稍有不同Unix下的select函数其参数1为操作的最大描述符的值加1。但是Windows下的select函数的第一个参数可以填最大的文件描述符加1,也可以默认填0(其参数1只是为了兼容而已)另外,Windows下的fd_set数据类型定义如下,其两个成员变量可以进行调用(但是Unix下的fd_set不提供),含义如下:fd_count:当前fd_set集合中存放的描述符的数量f原创 2021-07-01 19:18:55 · 160 阅读 · 0 评论 -
2---封装网络数据报
一、为什么设计网络数据报在消息交互时使用字符串不安全,且比较麻烦不好处理二、本文案例中用到的数据报格式本文的案例为:客户端可以输入login来登录服务端,或者输入logout来退出服务端服务端根据客户端传来的数据,做相应的回复消息类型枚举//消息的类型enum CMD{ CMD_LOGIN, //登录 CMD_LOGIN_RESULT, //登录结果 CMD_LOGOUT, //退出 CMD_LOGOUT_RESULT, //退出结果 CMD_E原创 2021-07-01 19:07:04 · 116 阅读 · 0 评论 -
1---Windows下Tcp Socket的基本结构(客户端、服务端)(转载)
1.服务端#define WIN32_LEAN_AND_MEAN#define _WINSOCK_DEPRECATED_NO_WARNINGS //for inet_pton() #include <windows.h>#include <WinSock2.h>#include <iostream> #pragma comment(lib, "ws2_32.lib") using namespace std; int main(){ WORD.原创 2021-07-01 17:25:55 · 203 阅读 · 0 评论 -
几种构造函数详解
有个老哥写的构造函数解析,觉得很不错,害怕以后csdn这sb又自动收费,转载过来保存下。转载地址class Complex { private : double m_real; double m_imag; public: // 无参构造函数 // 如果创建一个类你没有写任何构造函数,则系统会自动生成默认的无参构造函数,函数为空 // 只要你写了一个下面的某一种构造函数,系统就不会再自动生成这样一个 //默认构造函数,如果希望原创 2021-05-09 08:48:04 · 1401 阅读 · 0 评论 -
25 领域规则模式(Interpreter)
在特定领域中,某些变化虽然频繁,但可以抽象为某种规则。这时候,结合特定领域,将问题抽象为语法规则,从而给出在该领域下的一般性解决方案。①只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则问题”才适合Interpreter模式。②Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。...原创 2021-01-05 20:38:59 · 303 阅读 · 0 评论 -
23、24行为变化模式(Command、Visitor)
在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。命令模式(Command)①Command模式的根本目的在于将“行为请求者”和“行为实现者”解耦。②Command模式与C++中的函数对象有些类似。但两者定义行为接口的规范有所区别:Command以面向对象中的“接口-实现”来定义行为接口规范,更严格,但有性能损失;C++函数对象以函数签名来定义行为接口规范,更灵活,性能更高。访问器(Visito原创 2021-01-05 20:21:07 · 153 阅读 · 0 评论 -
20、21、22数据结构模式(Composite、Iterator、Chain of Resposibility)
常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定的数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问,是一种行之有效的解决方案。组合模式(Composite)①Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,使得客户代码可以一致地(复用)处理对象和对象容器,无需关心处理的是单个对象还是组合的对象容器。②将“客户代码与复杂对象容器结构”解耦是Compos原创 2020-12-29 21:00:25 · 121 阅读 · 0 评论 -
18、19状态变化模式(State、Memento)
在某些构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?状态变化模块为这一问题提供了一种解决方案。状态模式(State)①State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。②如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。备忘录(Memento)①Memento模式的核心是信息隐原创 2020-12-28 21:55:23 · 147 阅读 · 0 评论 -
14、15、16、17 接口隔离模式(Facade、Proxy、Adapter、Mediator)
在组建的构建过程中,某些接口之间直接的依赖常常带来许多问题、甚至根本无法实现。采用添加一层间接(稳定接口),来隔离本来互相紧密关联的接口是一种常见的解决方案。门面模式(Facade)①从客户的角度来看,Facade模式简化了整个组件系统的接口,对于组件内部与外部客户程序来说,达到了一种“解耦”的效果–内部子系统的任何变化不会影响到Facade接口的变化②Facade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。③Facade设计模式并非一个集装箱,可以任意地放进任何多个对象。Facad原创 2020-12-28 21:21:09 · 192 阅读 · 0 评论 -
12、13对象性能模式(Singleton、Flyweight)
面向对象很好的解决了“抽象”问题,但是不可避免地要付出一定的代价。对于通常情况来讲,面向对象的成本大多可以忽略不计。但在某些情况下,面向对象的成本必须谨慎处理。单例模式(Singleton)Singleton模式一般不要支持拷贝构造函数和Clone接口,因为这有可能导致多个对象实例,与Singleton模式初衷违背。享元模式(Flyweight)...原创 2020-12-28 19:39:09 · 102 阅读 · 0 评论 -
8、9、10、11对象创建模式(工厂方法、抽象工厂、原型模式、构建器)
通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合,从而支持对象创建的稳定。工厂方法(Factory Method)①Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致软件的软弱。②Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。③Factory Method模式解决单个对象的需求变化,缺点在于要求原创 2020-12-27 10:53:28 · 95 阅读 · 0 评论 -
6、7 单一职责模式(装饰模式、桥模式)
1.装饰模式(Decorator)①通过采用组合而非继承的方法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的灵活性差和多子类衍生问题②Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表示为has-a Component的组合关系,即Decorator类又使用另外一个Component类2.桥模式(Bridge)...原创 2020-12-25 09:46:11 · 144 阅读 · 1 评论 -
3、4、5 组件协作模式
1.模板方法(Template method)2.策略模式(Strategy)①Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间切换②Strategy提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式③如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销...原创 2020-12-19 10:12:54 · 70 阅读 · 0 评论 -
155 线程的相关操作
1.线程的挂起与恢复SuspendThread、ResumeThread线程的挂起和恢复是有次数的,挂起和恢复的次数是一一对应的2.线程的优先级①AfxBeginThread创建线程的时候直接指定②CreateThread需要创建之后指定。获取:GetThreadPriority 设置:SetThreadPriorityUINT _cdecl ThreadProc1(LPVOID lpParameter){ CStdioFile mFile; mFile.Open(_T("F:\\456.原创 2020-12-17 21:51:59 · 125 阅读 · 0 评论 -
154 、MFC中用户界面线程
界面线程的创建①从CWinThread类派生自己的子类:CUIThread②重载InitInstance(必须重载)与ExitInstance(可选重载)函数③在InitInstance函数界面中进行界面的创建④调用AfxBeginThread函数开启界面线程原创 2020-12-17 20:42:55 · 179 阅读 · 0 评论 -
2.面向对象设计原则
1.依赖倒置原则(DIP)①高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定)②抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)2.开放封闭原则(OCP)①对扩展开放,对更改封闭。②类模块应该是可扩展的,但是不可修改3.单一职责原则(SRP)①一个类应该仅有一个引起它变化的原因②变化的方向隐含着类的责任4.liskov替换原则(LSP)①子类必须能够替换它们的基类②继承表达类型抽象5.接口隔离原则(ISP)①不应该强迫客户程序依赖它们原创 2020-12-17 10:32:51 · 100 阅读 · 0 评论 -
152.创建线程的方式
1.CreateThread①需要释放线程资源 CloseHandle(要释放的线程句柄)②注意传递给线程过程的参数的类型2.AfxBeginThread①会创建工作线程和界面线程②工作线程建议不要去操作界面③注意传递给线程过程的参数的类型线程不需要自己释放3._beginthreadex注:①2,3是调用第1种方法...原创 2020-12-16 20:35:50 · 75 阅读 · 0 评论 -
内存分配方式
内存分配方式有三种:(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或原创 2020-11-22 20:52:09 · 179 阅读 · 0 评论 -
递归解法
转载:https://lyl0724.github.io/2020/01/25/1/#%E9%80%92%E5%BD%92%E8%A7%A3%E9%A2%98%E4%B8%89%E9%83%A8%E6%9B%B2相信很多初学者和我一样,这是一个思维误区,一定要走出来。既然递归是一个反复调用自身的过程,这就说明它每一级的功能都是一样的,因此我们只需要关注一级递归的解决过程即可。如上图所示,我们需要关心的主要是以下三点:1.整个递归的终止条件。2.一级递归需要做什么?3.应该返回给上一级的返回值是什转载 2020-10-15 22:33:05 · 397 阅读 · 0 评论 -
线程中join()和detach()的区别
参考1)C++11 concurrent progamming (1) join/detach2)c++多线程编程:join()函数与detch()函数的区别。区别#include<iostream>#include<thread>using namespace std;void function_1(){ std::cout << "Hello,world!" << std::endl;}int main() { std::threa原创 2020-10-04 21:00:18 · 3986 阅读 · 0 评论 -
前中后序的迭代和递归写法
前序递归class Solution { vector<int> res;public: vector<int> inorderTraversal(TreeNode* root) { if(root ==NULL ) { return res; } res.push_back(root->val); inorderTraversal(root->原创 2020-09-16 20:08:51 · 431 阅读 · 0 评论 -
回溯法问题理解
简介回溯法的基本原理是深度优先搜索,即所谓的尽可能深的搜索每一个图。它的基本思想是:首先访问图中的某一初始顶点v,,然后从v出发,访问相邻点w1,再访问w1的相邻点w2…重复上述过程。当不能再继续向下访问时,依次退回到最近被访问的顶点,若它还有邻接点未被访问,则从该点开始继续上述搜索过程,直到图中所有点均被访问过。回溯法的解题思路1.判断约束条件2. 进行回溯2.1 设置回溯初值,用于之后不成功返回2.2 将回溯初值置为0,避免重复访问2.3 进行上左下右试探,可行就成功2.4 失败就返回原创 2020-09-14 10:09:37 · 367 阅读 · 0 评论 -
无法打开包括文件: “flann/flann.hpp”: No such file or directory
1.第一步包含目录\PCL\3rdParty\FLANN\include\flann改为\PCL\3rdParty\FLANN\include,此时报错:第二步根据所提示的路径,找到dist.h文件,然后typedef unsigned long long pop_t语句转移到#if __GNUC__之前,就可以了。...原创 2020-09-12 21:19:11 · 2307 阅读 · 0 评论 -
windows10环境下tensorflow安装过程(CPU安装)
主要参考这里备注1.血的教训,在安装之前,一定要注意anaconda的版本,现在很多库不支持python3.7,又为python2比较老,许多功能不足,所以推荐安装python3.5或者python3.6,然后下载与python相对应的anaconda的版本。2.tensorflow的版本可以修改,版本看这里如果觉得文章有用,请给个赞...原创 2020-05-09 17:50:50 · 459 阅读 · 0 评论 -
C/C++语言中的变量的4种存储类型
1. C/C++语言中的变量的存储类型/数据类型存储类型:用来指明变量的存储位置,即运行该变量在哪一段分配内存空间,常见的存储位置有auto、extern、register、static,在一段执行程序中,可以为变量分配存储空间的有BSS(BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文BlockStarted by Symbol的简称。BSS段属于静态内存分配)、数据区(用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配)、栈区(原创 2020-07-30 23:10:32 · 2059 阅读 · 0 评论 -
指针和引用的相同点和不同点
1.相同点都是复合类型,都是地址的概念;指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。2.不同点2.1 初始化指针本身是一个对象,允许对指针进行赋值和拷贝,指针无须在定义时赋初值;引用本身并不是一个对象,定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用就无法重新绑定到另外一个对象,因此引用必须初始化,且初始化必须为一个对象。2.2 值是否能为空指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;2原创 2020-07-22 09:50:46 · 424 阅读 · 0 评论 -
(动态规划)322.零钱兑换
前言还几天没有更新博客,是不是想我了(自恋狂哈哈)。这几天主要是老板让研究pointnet,因为环境配置总是出些问题,(菜鸡一枚)所以耽搁了些时间。搞好了环境,然后看了几天pointnet代码,于是赶快来刷刷题。今天看的仍然是一道动态规划的题目。题目给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。示例 1:输入: coins = [1, 2, 5], amount = 11输出:原创 2020-05-12 23:57:09 · 135 阅读 · 0 评论 -
(动态规划)leetcode338:比特位计数
题目给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。示例 1:输入: 2输出: [0,1,1]示例 2:输入: 5输出: [0,1,1,2,1,2]来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/counting-bits分析开始这题可以使...原创 2020-04-26 16:59:13 · 283 阅读 · 0 评论 -
(动态规划)leetcode354:俄罗斯套娃的信封问题
题目给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。说明:不允许旋转信封。示例:输入: envelopes = [[5,4],[6,4],[6,7],[2,3]]输出:...原创 2020-04-21 09:33:42 · 450 阅读 · 0 评论 -
(动态规划)leetcode63:不同路径Ⅱ
题目一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?网格中的障碍物和空位置分别用 1 和 0 来表示。说明:m 和 n 的值均不超过 100。示例 1:输入:[[0,0,0]...原创 2020-04-19 14:30:49 · 138 阅读 · 0 评论 -
(动态规划)leetcode120:最小路径和
题目给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。例如,给定三角形:[[2],[3,4],[6,5,7],[4,1,8,3]]自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。说明:如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。来源:力扣(LeetCode)链接...原创 2020-04-19 09:35:47 · 153 阅读 · 0 评论 -
leetcode111:二叉树的最小深度
题目给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明: 叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null,15,7],3/ 9 20/ 15 7返回它的最小深度 2.来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/minimum-...原创 2020-04-17 22:22:45 · 130 阅读 · 0 评论 -
(位运算)leetcode201:数字范围按位与
题目给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。示例 1:输入: [5,7]输出: 4示例 2:输入: [0,1]输出: 0来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/bitwise-and-of-numbers...原创 2020-04-17 15:23:09 · 365 阅读 · 0 评论