当前位置: 首页 > ai >正文

【c/c++3】类和对象,vector容器,类继承和多态,systemd,stdboost

文章目录

  • 1.类和对象:结构体升级为类,C++中枚举类enum class,c中enum
  • 2.vector容器:vector与string类一样属于STL
  • 3.类继承和多态:子类可直接用父类属性和方法
  • 4.生成数据:手动执行bin不受systemd管控
    • 4.1 systemd:journalctl等带ctl都属于systemd,systemctl查看所有service状态
    • 4.2 crtsurfdata.cpp:字符拆分存入结构体再存入容器
  • 5.std&boost:下载boost库解压后执行编译和install脚本,一般.so或.a自动装在/usr/local/lib下


1.类和对象:结构体升级为类,C++中枚举类enum class,c中enum

C++动态内存分配:C语言动态分配内存用malloc(),释放内存用free()。C++中new和delete。
在这里插入图片描述
下面为三种show函数重载实现,如下字符串理论上可定义为char name[10],但函数里字符串也只能传地址,所以只能定义为char * name
在这里插入图片描述
在这里插入图片描述
构造函数:必须public属性,名字和类名相同,没有返回值(void也不允许),不能被显示调用(只能创建对象自动执行)。
在这里插入图片描述
析构函数:一个类只有一个,不允许被重载,清理工作如释放内存。
在这里插入图片描述
C中&取地址,C++中&引用。引用就像起别名=typedef=宏define。
在这里插入图片描述
在这里插入图片描述
C++中string随着存放字符长度自动伸缩,不用担心内存溢出。string类是一个模板类,位于std命名空间,如果不加using namespace std;就要用std::string str。string特性描述函数:int size()返回当前字符串大小int length()返回当前字符串的长度void clear()清空字符串。string本质是一个类,通过动态分配内存实现对字符串的存储,string对象用于存放字符的内存地址是变化的。也就是地址存放的下就不再重新分配,存放不下就重新分配地址。
在这里插入图片描述

2.vector容器:vector与string类一样属于STL

容器的使用:1.存放整数
在这里插入图片描述
访问容器中元素可以像数组形式一样。
在这里插入图片描述
2.存放字符串
在这里插入图片描述
3.存放结构体4.存放类:存放字符串中,string就是类。
在这里插入图片描述
vector其他成员函数:1.定位的函数
在这里插入图片描述
2.增加元素的函数
在这里插入图片描述
3.删除元素的函数
在这里插入图片描述
4.判断容器的大小
bool empty():判断容器是否为空
int size():返回容器中元素的个数
5.作业题:封装随机数
在这里插入图片描述

//此程序用于生成一组随机数, 指定数组范围和是否重复
#include"_public.h"class CRand
{
public:CRand();~CRand();vector <int> m_val;  //m_val容器	bool checkexit(const int aryyval, const int aryysize); // 用于检查是否为重复数据,aryyval为重复的值,这函数不单用,用于Rand成员函数里void Rand(const int minvalue,const int maxvalue,bool brep=true, const int nog=5); //brep为是否允许重复; 默认为允许重复,nog指定生成多少个随机数
};//111111111111111111111111111111111111111111111111111111111111111111111111111111
void CRand::Rand(const int minvalue,const int maxvalue,bool brep,const int nog)
{int len = maxvalue-minvalue;int ii=0, itmp=0, jtmp=0;  // ii生成第几个,jtmp实际生成共多少个,itmp生成的值m_val.clear();if(brep==true)    // 允许重复{jtmp = nog;for(ii=0;ii<jtmp;ii++){itmp = rand()%(len+1)+minvalue; // (0~len)+minvalue,itmp就是min~max之间的值,不是len长度m_val.push_back(itmp);    }return; //return是函数直接返回, 也就是结束该函数。//要跳出循环用break, if代码段是不能用break跳出的, 在一个函数内任意位置调用return, 直接退出Rand函数,下面代码不执行。}jtmp = nog;    // 以下为不允许重复 ,因为没进入if(brep==true)if (nog>len) jtmp = len + 1;  // 比如5-1=4,但1到5可以生成5个,所以如果nog大于len的话就取len+1个,前提不允许重复。while(1)   {if (jtmp == m_val.size()) break;  //生成满了跳出循环itmp = rand()%(len+1)+minvalue;if (ii==0)  // 生成第一个不用管checkexit重不重复{m_val.push_back(itmp);ii++;continue;} if (checkexit(itmp,ii) == false) continue;  // checkexit为false则不允许重复m_val.push_back(itmp); ii++;}return;
}//11111111111111111111111111111111111111111111111111111111111111111111111111111
bool CRand::checkexit(const int aryyval, const int aryysize) // aryyval重复的值,aryysize允许多少个重复
{for (int ii=0; ii<aryysize; ii++){if (aryyval == m_val[ii]) return false;}return true;
}CRand::~CRand()
{m_val.clear();
}CRand::CRand()
{struct timeval begin;gettimeofday(&begin, 0);srand(begin.tv_usec);
}//1111111111111111111111111111111111111111111111111111111111111111111111111111111111
int main()   //如何用CRand这个类
{CRand CrtRand;CrtRand.Rand(0, 10, false);   // 若false为true允许重复,不管范围多少取nog个for(int ii=0;ii<CrtRand.m_val.size();ii++){printf("%d\n",CrtRand.m_val[ii]);}	return 0;
}

3.类继承和多态:子类可直接用父类属性和方法

类多态:子类必重写父类纯虚函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.生成数据:手动执行bin不受systemd管控

4.1 systemd:journalctl等带ctl都属于systemd,systemctl查看所有service状态

linux开机自动启动脚本:/etc/rc.localcrontab rc.d【sudo update-rc.d a.sh defaults 90,90表明一个优先级,越高表示执行的越晚,a.sh在/etc/init.d/里】, systemd【Restart=on failure是失败会继续执行,默认执行5次(同rc.d中sv restart sensor-mon),Type=oneshot是无论怎样就只执行一次】。
在这里插入图片描述
systemd 可以管理所有系统资源,不同的资源统称为Unit,一共分如下12种:systemctl --state failed | catsystemctl list-dependencies --type=service --no-pager
在这里插入图片描述
在这里插入图片描述
target是特殊的unit,它不执行任何实际的操作,作用把一组unit利用各种依赖和包含关系组织起来共同完成某件事情。systemd用目标(target)替代了initd中运行级别的概念:
在这里插入图片描述

# systemctl get-default   # 查询当前默认开机运行的target
multi-user.target
# systemctl cat multi-user.target
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target   # 要求basic.target一起运行
Conflicts=rescue.service rescue.target  # 如果rescue.service或rescue.target正在运行,multi-user.target就不能运行,反之亦然
After=basic.target rescue.service rescue.target
AllowIsolate=yes  # 允许使用systemctl isolate命令切换到multi-user.target# service-a.service
Requires=service-b.service
After=service-b.service
# service-b.service会在service-a重启时自动重启
Type=simple
ExecStart=/usr/bin/b
Restart=always# 在/etc/systemd/system/reboot.target.d/refuse.conf中添加:则禁止systemctl start reboot.target
[Unit]
RefuseManualStart=yes
RefuseManualStop=yes

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2 crtsurfdata.cpp:字符拆分存入结构体再存入容器

在这里插入图片描述
在这里插入图片描述
如下每星期每月每日每小时的第20分钟到第40分钟每分钟都会执行一次(1小时执行21次)。
在这里插入图片描述
在这里插入图片描述
crontab -e进入如下,dow表示星期。
在这里插入图片描述

// makefile
CC=g++
FLAG=-g
#FLAG=-02
all:crtsurfdata
crtsurfdata:crtsurfdata.cpp _public.h _public.cpp   // _public.h _public.cpp改变也要重新编译$(CC) $(FLAG) -o crtsurfdata crtsurfdata.cpp _public.cpp cp crtsurfdata ../bin/.
clean:rm -rf crtsurfdata

在这里插入图片描述
在这里插入图片描述

#include "_public.h" // 安徽,58102,亳州,33.47,115.44,39.1,_public.h同目录
// 全国气象 (站点参数stcode) 数据结构
struct st_stcode
{char provname[31];   // 省名称char obtid[11];      // 站点代码 //也可能是字母所以用字符串表达char cityname[31];   // 城市名double lat;          // 纬度double lon;          // 经度double height;       // 海拔高度
};
// 全国气象站点分钟 (生成的观测数据surfdata) 数据结构
struct st_surfdata
{char obtid[11];      // 站点代码char ddatetime[21];  // 数据时间:格式yyyy-mm-dd hh24:mi:ss。int  t;              // 气温:单位,0.1摄氏度int  p;              // 气压:0.1百帕 int  u;              // 相对湿度,0-100之间的值。int  wd;             // 风向,0-360之间的值。int  wf;             // 风速:单位0.1m/sint  r;              // 降雨量:0.1mmint  vis;            // 能见度:0.1米
}; 
vector<struct st_stcode> vstcode;   // 存放全国站点参数的容器  //将结构体放入容器中,就直接操作容器了
vector<struct st_surfdata> vsurfdata;   // 存放全国气象站点分钟观测数据的容器
// 从站点参数文件中加载到vstcode容器中,在函数里字符串只能传地址
bool LoadSTCode(const char *inifile);
// 创建全国气象站点分钟观测数据,存放在vsurfdata容器中
void CrtSurfData();
// 把容器vsurfdata中的全国气象站点分钟观测数据写入文件
bool CrtSurfFile(const char *outpath);
CLogFile logfile;
void EXIT(int sig);int main(int argc,char *argv[],char *envp[])    //*argv[]:指针的数组,也可以**argv指针的指针
{  if (argc!=4){  printf("\n本程序用于生成全国气象站点观测的分钟数据。\n");printf("/root/qxidc/bin/crtsurfdata 站点参数 数据文件存放的目录 日志文件名\n");printf("例如:/root/qxidc/bin/crtsurfdata /root/qxidc/ini/stcode.ini /root/qxidc/data/ftp/surfdata /root/qxidc/log/crtsurfdata.log\n");  //目录自动创建return -1;  //程序没有捕获运行结果,所以0,-1无所谓,return -1失败跳出大循环,return 0成功}// 关闭全部输入输出和信号,也可写成void CloseIOAndSignal(); 下面printf失效CloseIOAndSignal();// 因为程序运行需要退出,所以捕获退出信号(ctrl+c或kill/kill all),signal将这两个信号值作为sig参数传给EXIT函数signal(SIGINT,EXIT); signal(SIGTERM,EXIT);  //可以ctrl+c或kill/kill all通知程序退出  if (logfile.Open(argv[3],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[3]); return -1;}// 可把while (true)一行和sleep(60)去除,用crontab调度,不能多进程中(在某一进程中关闭指针文件,其他就全部关了不会再打开)// 这段代码编出来的crtsurfdata二进制文件运行一次1秒不到就执行完,没必要死循环浪费内存while (true)  {// 从站点参数文件中加载到vstcode容器中,argv[0]计算机从0开始if (LoadSTCode(argv[1])==false) { sleep(60); continue; }    logfile.Write("加载参数文件(%s)成功!\n",argv[1]);CrtSurfData();  // 生成全国气象站点分钟观测数据,存放在vsurfdata容器中// 把容器vsurfdata中的全国气象站点分钟观测数据写入文件if (CrtSurfFile(argv[2])==false) { sleep(60); continue; }sleep(60);  // 进入死循环60s执行一次,自身调度自己}return 0;
} //11111111111111111111.从站点参数文件中加载到vstcode容器中
bool LoadSTCode(const char *inifile)
{vstcode.clear();CCmdStr CmdStr;  // CmdStr类(_public.h中)切分并暂存字符串struct st_stcode stcode;  // st_stcode为数据结构,stcode为结构体变量CFile File;if (File.Open(inifile,"r") == false){logfile.Write("File.Open(%s) 失败。\n",inifile); return false;}char strbuffer[101];  //101个字节可以存放50个汉字  strbuffer就是stcode.ini站点参数内容while (true){memset(&stcode,0,sizeof(struct st_stcode));// memset(strbuffer,0,sizeof(strbuffer)); 因为Fgets里有初始化,所以这行省去    if (File.Fgets(strbuffer,100)==false) break; // 读取一行,在循环里就多行读取,break不能写成return falseCmdStr.SplitToCmd(strbuffer,",",true); // true为删除空格,CmdStr里存了一行拆分后的片段,循环里就是多行CmdStr.GetValue(0, stcode.provname);  //stcode.provname就存了拆分的值,在循环里CmdStr.GetValue(1, stcode.obtid);     //GetValue做了重载,有第三个参数取长度CmdStr.GetValue(2, stcode.cityname);CmdStr.GetValue(3,&stcode.lat);  //double 传地址&CmdStr.GetValue(4,&stcode.lon);     CmdStr.GetValue(5,&stcode.height);vstcode.push_back(stcode);	// printf("strbuffer=%s",strbuffer);   //不需写成strbuffer=%s\n,因为文件本身有换行符// printf("provname=%s,obtid=%s,lat=%.2lf\n.....",stcode.provname,stcode.obtid,stcode.lat,......);}return true;
}//1111111111111111112.创建全国气象站点分钟观测数据,存放在vsurfdata容器中,//Crt是create缩写
void CrtSurfData()  // 返回一定会成功的,所以不需要返回值void
{vsurfdata.clear();  // 清空容器srand(time(0));     // 播随机数种子  char strLocalTime[21];  LocalTime(strLocalTime,"yyyy-mm-dd hh24:mi"); // LocalTime3个参数:一:存放时间的字符串。二:取出当前时间用什么格式。三:时间偏移量秒。将memset(strLocalTime,0,sizeof(strLocalTime));放入LocalTime()中strcat(strLocalTime,":00"); //不计秒,里面800多行记录时间和文件名时间一样就把秒变成00struct st_surfdata stsurfdata;for (int ii=0;ii<vstcode.size();ii++)  //根据站点代码个数{memset(&stsurfdata,0,sizeof(struct st_surfdata)); STRCPY(stsurfdata.obtid,10,vstcode[ii].obtid);  // 站点代码  //STRCPY(目的,长度,源)// LocalTime(stsurfdata.ddatetime);STRCPY(stsurfdata.ddatetime,20,strLocalTime);   // 数据时间采用当前时间stsurfdata.t=rand()%351;       // 气温:单位,0.1摄氏度  // 结构体值 //0-350间整数就行stsurfdata.p=rand()%265+10000; // 气压:0.1百帕  //0到264再加10000就是10000到10264stsurfdata.u=rand()%100+1;     // 相对湿度,1-100之间的值。stsurfdata.wd=rand()%360;      // 风向,0-360之间的值。stsurfdata.wf=rand()%150;      // 风速:单位0.1m/sstsurfdata.r=rand()%16;        // 降雨量:0.1mmstsurfdata.vis=rand()%5001+100000;  // 能见度:0.1米vsurfdata.push_back(stsurfdata);}
}//1111111111111111113.把容器vsurfdata中的全国气象站点分钟观测数据写入文件
bool CrtSurfFile(const char *outpath)
{CFile File;char strLocalTime[21];LocalTime(strLocalTime,"yyyymmddhh24miss");char strFileName[301]; //目录名+文件名即下行outpath+/SURF_ZH_%s_%d.txt,初始化也在SNPRINTF中SNPRINTF(strFileName,300,"%s/SURF_ZH_%s_%d.txt",outpath,strLocalTime,getpid());  // outpath目录名   if (File.OpenForRename(strFileName,"w")==false){logfile.Write("File.Open(%s) 失败!\n",strFileName); return false; // 不用printf显示到屏幕了}for (int ii=0;ii<vsurfdata.size();ii++) //装进容器里就是为了这行循环{// 站点代码,数据时间,气温,气压,相对湿度,风向,风速,降雨量,能见度  //存进容器的是整数,除以小数得小数显示到文件中File.Fprintf("%s,%s,%.1f,%.1f,%d,%d,%.1f,%.1f,%.1f\n",\vsurfdata[ii].obtid,vsurfdata[ii].ddatetime,vsurfdata[ii].t/10.0,vsurfdata[ii].p/10.0,\vsurfdata[ii].u,vsurfdata[ii].wd,vsurfdata[ii].wf/10.0,vsurfdata[ii].r/10.0,vsurfdata[ii].vis/10.0);}File.CloseAndRename();   // 关闭文件logfile.Write("生成数据文件(%s)成功,数据时间=%s,记录数=%d!\n\n",strFileName,vsurfdata[0].ddatetime,vsurfdata.size()); // 数据时间=和文件名时间一样就是最后秒改为00(即文件里839行【vsurfdata.size()行】记录时间)vstcode.clear(); vsurfdata.clear(); //这里不清空容器,记录数=839,1678....(除非每次运行都重新make,不然要清空容器)return true;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);  // killall crtsurfdata ,.log日志文件中记录了:时间..程序退出,sig=15exit(0); //exit(0)程序退出自然会调用logfile的析构函数,所以这里不需要调用
}

在这里插入图片描述

5.std&boost:下载boost库解压后执行编译和install脚本,一般.so或.a自动装在/usr/local/lib下

在这里插入图片描述

#include <iostream>
#include <string>
#include <utility>
std::pair<int, int> divide(int dividend, int divisor) {int quotient = dividend / divisor; // 除数int remainder = dividend % divisor;  // 余数return std::make_pair(quotient, remainder);
}
int main() {std::pair<int, int> result = divide(10, 3);std::cout << "Quotient: " << result.first << ", Remainder: " << result.second << std::endl;  // Quotient: 3, Remainder: 1return 0;
}
int main() {std::string str1 = "Hello";std::string str2 = std::move(str1);std::cout << "str1: " << str1 << std::endl;  // 此时 str1 的内容已经被移动,为空std::cout << "str2: " << str2 << std::endl;  // 输出 "Hello"return 0;
}
#include <iostream>
#define INFO_LOG Logger<true>(std::cout)  // true为false时,日志代码在编译期被完全移除
// Logger 类的构造函数需要一个 std::ostream&(输出流引用)参数,std::cout是标准输出流的全局实例,代表控制台输出
template <bool active>
struct Logger
{std::ostream& stream;Logger(std::ostream& _stream) : stream(_stream){if constexpr (active)  // true{stream << std::dec; // 强制设为十进制格式,C++流对象(如 std::cout)保留格式状态(如十六进制、八进制等)}}template <typename T>   // 模板参数支持任意数据类型Logger& operator<<(const T& value){if constexpr (active){stream << value;   // 实际输出}return *this;}~Logger(){if constexpr (active){stream << std::endl; // 输出换行并刷新缓冲区}}
};
int main() {INFO_LOG << "Starting SPD ownership";  // 串口打印INFO_LOG << std::hex << 255;  // 输出 "255" 而不是 "ff"(构造函数中的std::dec会重置格式)
}
int main() {std::cout << "222" << std::endl;
}
void a()
{std::cout << "111" << std::endl;
}
void a() __attribute__((constructor));  // main函数之前执行$ g++ a.cpp -o a
$ ./a
111
222
int main(int argc, char **argv) {static std::deque<bool>liquidStatus = {true, true, true};int status = 0; // 如下0 false,1 truebool nowLiquidStatusFlag = status ? true : false;std::cout << "nowLiquidStatusFlag is : " << std::boolalpha << nowLiquidStatusFlag << std::endl;liquidStatus.push_back(nowLiquidStatusFlag);liquidStatus.pop_front();  // 移除队列最前面的元素std::cout << "Current liquidStatus: ";for (bool val : liquidStatus) {std::cout << val << " "; // 最后空格}std::cout << std::endl; // 换行uint8_t data = 0x1c;if (data & 0x10) // bit4=1,不用>>4,非0进入{std::cout << "val非0" << std::endl;}return 0;
}

在这里插入图片描述
在这里插入图片描述
指针对内存的访问,肯定对应一段内存空间,引用是别名,指针不用初始化,引用必须初始化。引用不能为空。指针可以赋不同的值,引用只能绑定一个变量
在这里插入图片描述
string_view对字符串的处理,不用把字符串拷贝,直接赋值就行。调用dbus获取property时是字符串类型还是uint8/16等都可以用any或variant,不会崩溃。

智能指针将new和delete自动化实现,自动释放指针资源,shared_ptr共享指针。
在这里插入图片描述
左值:在内存有分配空间,可以取地址,在等于号左边,不是临时变量

如字符串常量就是右值

move能将左值转为右值,将左值中的值取出来,内存空间不会去使用,左值中的值也不存在了,这样就不用复制开辟一个新内存,如果不加move(左值),可能要开辟新内存用拷贝构造函数,现在用移动构造函数,只取值,不用深拷贝,不用新开辟内存,把值赋到新内存上,不消耗性能

http://www.xdnf.cn/news/14706.html

相关文章:

  • 「Java案例」输出24个希腊字母
  • 双指针的用法
  • Vue 3 Teleport 特性
  • 人工智能之数学基础:如何判断正定矩阵和负定矩阵?
  • 矩阵的逆 线性代数
  • LRU缓存设计与实现详解
  • Spring Cloud:服务监控与追踪的高级实践
  • C# 合并两个byte数组的几种方法
  • 零基础学习RabbitMQ(5)--工作模式(1)
  • C/C++数据结构之动态数组
  • ali PaddleNLP docker
  • vue-31(Nuxt.js 中的数据获取:asyncData和fetch)
  • XIP (eXecute In Place)
  • Spring AI Alibaba Nacos 集成实践
  • 【C++ 基础】 C++ 与 C 语言差异面试题(附大厂真题解析)
  • 【智能协同云图库】智能协同云图库第三弹:基于腾讯云 COS 对象存储—开发图片模块
  • 【Linux高级全栈开发】2.3.1 协程设计原理与汇编实现2.3.2 协程调度器实现与性能测试
  • 原型设计Axure RP网盘资源下载与安装教程共享
  • 【记录】服务器多用户共享Conda环境——Ubuntu24.04
  • 进阶向:Django入门,从零开始构建一个Web应用
  • Word之电子章制作——1
  • kubectl exec 原理
  • 力扣第73题-矩阵置零
  • Flutter基础(Children|​​Actions|Container|decoration|child)
  • git使用详解和示例
  • 【区块链】区块链交易(Transaction)之nonce
  • 【Docker基础】Docker容器管理:docker stats及其参数详解
  • C++共享型智能指针std::shared_ptr使用介绍
  • 机器学习配置环境
  • 某音Web端消息体ProtoBuf结构解析