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

C++回顾 Day5

自实现string完整版

my_string.h

using namespace std;
class mystr{public://mystr();mystr(const char * new_str = nullptr);mystr(const mystr & another);char * c_str();~mystr();mystr& operator=(const mystr & another);mystr operator+(const mystr & another);bool operator==(const mystr & another);bool operator<(const mystr & another);bool operator>(const mystr & another);char &operator[](int index);char at(int index);private:char * str;int len;
};

my_string.cpp

#include "my_string.h"
#include <string.h>
using namespace std;/*
mystr::mystr()
{str = new char[1];*str = '\0';
}
*/mystr::mystr(const char * new_str)
{if(new_str == nullptr){len = 0;str = new char[len + 1];*str = '\0';}else{len = strlen(new_str);str = new char[len + 1]; strcpy(str,new_str);}
}mystr::mystr(const mystr & another)
{//深拷贝this->len = strlen(another.str);this->str = new char[this->len + 1];strcpy(this->str,another.str);
}char * mystr::c_str()
{return str;
}mystr::~mystr()
{delete []str;
} mystr& mystr::operator=(const mystr & another)
{//深赋值if(this == &another){return *this;}else{delete []this->str;this->len = strlen(another.str);this->str = new char[this->len + 1];strcpy(this->str,another.str);return *this; }}
mystr mystr::operator+(const mystr & another)
{mystr new_str;delete []new_str.str;new_str.len = strlen(this->str) + strlen(another.str);new_str.str = new char[new_str.len + 1];strcpy(new_str.str,this->str);strcat(new_str.str,another.str);return new_str;
}
bool mystr::operator==(const mystr & another)
{if(strcmp(this->str,another.str) == 0)return true;elsereturn false;
}
bool mystr::operator<(const mystr & another)
{if(strcmp(this->str,another.str) < 0)return true;elsereturn false;
}
bool mystr::operator>(const mystr & another)
{if(strcmp(this->str,another.str) > 0)return true;elsereturn false;
}
char & mystr::operator[](int index)
{return this->str[index];
}
char mystr::at(int index)
{return this->str[index];
}

main.cpp

#include <iostream> 
#include "my_string.h"
using namespace std;int main()
{mystr str1;mystr str2("abcdefg");mystr str3(str2);mystr str4("abcdeffg");cout << "str1:" << str1.c_str() << endl;cout << "str2:" << str2.c_str() << endl;cout << "str3:" << str3.c_str() << endl;cout << "str4:" << str4.c_str() << endl;if(str2 < str4){cout << "str2 < str4" << endl;}else if(str2 == str4){cout << "str2 == str4" << endl;}else{cout << "str2 > str4" << endl;}cout << "str2[2] = " << str2[2] << endl;cout << "str4[4] = " << str4[4] << endl;return 0;
}

注意:

  1. 在写默认构造参数的时候一定要带上无参的那部分,不然在构造对象数组的时候就会有麻烦;

  2. 在有新对象并且默认构造参数有new的步骤就要先delete

  3. 如果函数会产生一个新对象就不能用引用作为返回类型,因为新对象在栈上,我们不能返回一个栈上的引用

  4. 如果只是在原本的对象上进行修改,一定要加上引用,这样才能反馈回原对象上

  5. 对于非拷贝构造函数的其他进行赋值的函数(重载=或者重载+等符号),一定要先delete作为最终容器的对象的内存,不然原来指向的那块内存会出现double delete的问题

对于成员函数,不单独为每个对象中的成员函数都分配独立空间而是公共空间,在调用函数时实际上还传入了该对象的指针——this

const关键字

在修饰成员变量的时候,这个变量的初始化只能在构造函数的参数列表里面

要修饰函数本身,const要放在声明之后,实现体之前 e.g. void myfunc()const{}

const修饰的函数和对象承诺:可以保证对象内的数据成员不会被修改;但只能访问const类的成员函数

const修饰函数本身也能构成重载

const修饰函数,是从函数的角度不能修改数据成员,只能调用const成员函数;

const修饰对象,是从对象的角度不能修改数据成员,只能调用const成员函数;

static关键字

用来修饰类内的数据成员时会使其作为共享数据,其内存与成员函数一样的存储规则,可以由簇类对象共同访问

static类成员在类声明的时候就已经开辟了空间

static类成员必须类内定义,类外初始化

static是属于类的,也是属于对象的,但终归是属于类的

在类还未实例化的时候就可以通过类名去访问static类数据成员 cout << A::share << endl;

static修饰的成员函数用来管理成员变量,其是属于类的,也是属于对象的,但终归是属于类的

static修饰的成员函数也只能访问static类的数据成员及static类的成员函数(与const不同,const多出一个可以访问非const成员变量,但是static不可以)

static const成员要就地初始化 e.g. static const int a = 8;

指向类成员变量的指针

变量类型 类名:: *指针名 = &类名::变量名
#include <iostream>
#include <string.h>
using namespace std;class stu
{public:stu(int perid,string pername):id(perid),name(pername){}~stu(){}int id;string name;
};int main()
{stu stu1(07,"bob");string stu::*p = &stu::name;cout << stu1.*p << endl;return 0;
}

q:string stu::*p = &stu::name;解释一下

a:假设我们有一个名为stu的类,这个类中有一个成员变量name。这行代码的目的是创建一个指向stu类成员name的指针。

让我们分解这行代码:

  • string stu::*:这部分声明了一个指针,这个指针不是指向普通的变量或对象,而是指向stu类的某个成员。由于成员name的类型是string(假设stringstd::string的简写,即C++标准库中的字符串类型),因此这个指针的类型是string stu::*,意味着它指向stu类的一个string类型的成员。

  • p:这是指针变量的名称。

  • = &stu::name;:这部分将指针p初始化为指向stu类的name成员。&stu::name是获取成员name的地址的方式,但这里的地址不是普通的内存地址,而是成员在类中的相对地址或者说是成员的偏移量。这是因为类的成员在内存中的实际位置取决于对象的起始地址和成员在类中的定义顺序。

综上所述,string stu::*p = &stu::name;这行代码创建了一个名为p的指针,它指向stu类的name成员。这样的指针允许你在拥有stu类对象的情况下,通过指针访问或修改该对象的name成员,即使你不知道对象的实际类型(在支持多态性的情况下)或者你想以一种通用的方式处理多个对象的相同成员。

指向类成员函数的指针

函数返回类型 类名:: *函数指针名(参数列表) = &类名::成员函数名
#include <iostream>
#include <string.h>
using namespace std;class stu
{public:stu(int perid,string pername):id(perid),name(pername){}~stu(){}void print(){cout << id << ' ' << name << endl;}int id;string name;
};int main()
{stu stu1(7,"bob");string stu::*p = &stu::name;void (stu::*pf)()= &stu::print;(stu1.*pf)();return 0;
}

这里也是一样的,右边是对stu作用域下的函数print进行取地址,由于print是void类型且在stu作用域下,左边就要用对应类型void stu::*进行接收;

此函数指针只是对于类的偏移量,要调用先进行实例化

又因为()优先级太高,会和print优先结合,故此前面需要加()

q:指向一个类中的成员函数的指针是这个样子void (stu:: * pf)()= &stu::print;,那指向一个类中的静态成员函数的指针是不是void (stu:: * pf)()= stu::print;

a:指向类中静态成员函数的指针的语法与指向普通成员函数的指针有所不同。具体来说,静态成员函数不属于类的任何特定对象实例,因此指向静态成员函数的指针的类型不需要包含类对象指针。

假设有一个类 stu 和一个静态成员函数 print,定义如下:

class stu {
public:static void print() {// 静态成员函数实现}
};

指向静态成员函数的指针应该定义为一个函数指针,其类型与静态成员函数匹配,而不是像指向普通成员函数的指针那样需要类对象指针。指向 stu 类中静态成员函数 print 的指针定义如下:

cpp复制代码void (*spf)() = &stu::print;

这里 spf 是一个指向静态成员函数 print 的指针。注意,这里使用的是普通的函数指针语法,而不是指向成员函数的指针语法。这是因为静态成员函数不依赖于任何类的实例

总结一下:

  • 指向类中普通成员函数的指针:返回类型 (类名::* 指针名)(参数列表) = &类名::成员函数名;

  • 指向类中静态成员函数的指针:返回类型 (* 指针名)(参数列表) = &类名::静态成员函数名;

借用指向类中静态成员函数的指针来调用对应函数可以(*pf)()也可以pf()

当创建对象时使用动态内存管理

#include <iostream>
#include <string.h>
using namespace std;class stu
{public:stu(int perid,string pername):id(perid),name(pername){}~stu(){}void print(){cout << id << ' ' << name << endl;}int id;string name;
};int main()
{string stu::*p = &stu::name;void (stu::*pf)()= &stu::print;stu *stu2 = new stu(18,"dick");cout << stu2->*p << endl;(stu2->*pf)();return 0;
}

由于使用的是new,此时的stu2是一个指针,故之前的.* 运算符变成了->*运算符

注意:非静态成员函数想要调用必须实例化,因为其可能改变成员变量的值,未实例化连成员变量都没有,是不对的

对指向成员函数的指针的应用

#include <iostream>
using namespace std;class func
{public:func(){fun_array[0] = &func::print_f;fun_array[1] = &func::print_g;fun_array[2] = &func::print_i;fun_array[3] = &func::print_j;}void usefun(int index){(this->*fun_array[index])();}private:void print_f(){cout << "void print_f()" << endl;}void print_g(){cout << "void print_g()" << endl;}void print_i(){cout << "void print_i()" << endl;}void print_j(){cout << "void print_j()" << endl;}void (func::*fun_array[4])() = {nullptr};
};int main()
{func test;test.usefun(2);
}

对于取成员函数的地址,接收和取地址时一定要带上类作用域

函数指针数组固定定义格式:返回类型 (类名::* 数组名[数组大小])() = {nullptr}

对于存放函数指针的值来说,解引用只能变为函数名,想要调用就要*函数指针()

对于使用了类作用域而指向了类内的成员(成员函数或者成员变量),只能使用-> * 和 .*使用

又因为成员函数指针只是对于类的偏移量,要调用先进行实例化,所以必须带this

q:void* * fun_array = new void *[4]{nullptr}; 这个的意思不是说要new一个数组,这个数组里面存储的数据类型都是void *吗,要接收一个void * 类型的数组的指针才是void * * ,然后再void print_f(){};fun_array[0] =&print_f;这不是在取void函数的地址也就是void *存到存放void *类型的数组里面吗?

a:

  1. 关于 void** fun_array = new void*[4]{nullptr};

    这行代码确实是在动态分配一个包含4个元素的数组,数组的类型是 void* 的指针(即每个元素都是一个指向 void 的指针)。而整个数组由一个指向 void* 的指针 fun_array 来管理。这里的 void** 表示的是一个指向 void* 的指针,也就是一个指针的指针,它指向的是一个 void* 类型的数组。

  2. 关于 void print_f(){};fun_array[0] = &print_f;

    • void print_f(){}; 定义了一个返回类型为 void 的函数 print_f,它不接受任何参数。

    • fun_array[0] = &print_f; 这行代码试图将函数 print_f 的地址赋给 fun_array[0]。但是,这里有一个类型不匹配的问题:&print_f 是一个指向 void()(即返回 void 且不接受参数的函数)的指针,而 fun_array[0] 是一个 void* 类型的指针。在 C++ 中,函数指针和 void* 指针是不兼容的,不能直接赋值。

    如果您想要存储函数指针,您需要确保函数指针的类型与数组元素的类型相匹配。由于 print_f 是一个返回 void 的函数,其指针类型应该是 void (*)()(一个指向返回 void 且不接受参数的函数的指针)。

q:不是说函数名就是地址吗?为啥不能fun_array[0] = func::print_f;?

a:在 C++ 中,确实有一个常见的说法“函数名就是地址”,这指的是函数名在大多数情况下可以用作指向该函数的指针。然而,这个说法有几个重要的限制和上下文需要注意:

  1. 静态成员函数与非静态成员函数:对于静态成员函数,函数名确实可以直接用作函数指针。但是,对于非静态成员函数,情况就不同了。非静态成员函数需要一个类的实例来调用,因此它们不能简单地赋值给一个普通的函数指针。相反,它们需要特殊的成员函数指针类型。

  2. 成员函数指针的语法:在 C++ 中,成员函数指针的声明和使用比普通函数指针更复杂。成员函数指针不仅需要指向函数,还需要知道它是哪个类的成员函数。

友元

函数可以做友元,称为友元函数

当友元函数是是一个全局函数时

#include <iostream>
using namespace std;class A
{public:A(int a = 5,int b = 10):a(a),b(b){}~A(){}friend void show(A &my_A);private:int a;int b;
};void show(A &my_A)
{cout << my_A.a << ' ' << my_A.b << endl;
}int main()
{A myA1;A myA2(10,20);show(myA1);show(myA2);
}

友元关键字friend最好写到public里面

当友元函数在其他类中充当成员函数时

#include <iostream>
using namespace std;class A;	//进行先前声明(这种声明只能让编译器理解A类型的引用和指针)class B
{public:void show(A &my_A);		//函数实现体里面出现了A的成员,那就要写在A完整定义之后
};class A
{public:A(int a = 5,int b = 10):a(a),b(b){}~A(){}friend void B::show(A &my_A);	//谁的作用域在其他类里面出现了谁就要先完整定义private:int a;int b;
};void B::show(A &my_A)
{cout << my_A.a << ' ' << my_A.b << endl;
}int main()
{A myA1;A myA2(10,20);B my_B; my_B.show(myA1);my_B.show(myA2);
}

友元类

#include <iostream>
#include <string.h>
using namespace std;class son
{public:son(int id = 0,char nannv = 'm',string name = "bob"):id(id),nannv(nannv),name(name){}~son(){}friend class father;private:int id;char nannv;string name;
};class father
{public:void getid(son &myson){cout << myson.id << endl;}void getnannv(son &myson){cout << myson.nannv << endl;}void getname(son &myson){cout << myson.name << endl;}
};int main()
{son a1;son a2(7,'w',"dick");father b;b.getid(a1);b.getnannv(a1);b.getname(a1);b.getid(a2);b.getnannv(a2);b.getname(a2);
}

注意:

  1. 友元关系不能被继承

  2. 友元关系是单向的,a是b的友元,a可以访问b的private类成员,但是b不可以访问a的private类成员

  3. 友元关系不具有传递性,b是a的友元,c是b的友元,c不一定是a的友元

对于于是运算符的重载函数,写成友元函数和成员函数在运行时有本质区别

#include <iostream>
using namespace std;class sett
{public:sett(int x = 0,int y = 0,int z = 0):x(x),y(y),z(z){}//sett operator+(const sett& another);friend sett operator+(const sett &a,const sett& b);void show();private:int x;int y;int z;
};//sett sett::operator+(const sett& another)//成员函数自带this指针所以只需一个额外参数
//{
//	sett t;
//	t.x = this->x + another.x;
//	t.y = this->y + another.y;
//	t.z = this->z + another.z;
//	return t;
//}sett operator+(const sett &a,const sett& b)//友元函数要传两个
{sett t;t.x = a.x + b.x;t.y = a.y + b.y;t.z = a.z + b.z;return t;
}void sett::show()
{cout << x << ' ' << y << ' ' << z << endl;
}int main()
{sett a(1,2,3);sett b(2,3,4);sett c = a + b;//如果是友元函数,就是sett c = operator+(a,b);//如果是成员函数,就是sett c = a.operator+(b);a.show();b.show();c.show();return 0;
}

对于+加法运算符来说,(a + b) = c是不可以的,但是如果是上面的写法就是可以的,不管是sett operator+(const sett &a,const sett& b)还是sett operator+(const sett& another)都是在栈上创建一个新对象,(a + b) = c相当于在栈上创建了一个sett类的对象,使其等于a+b的结果,然后又将c付给了这个新对象,紧接着这个栈就消失了,这个新对象也随之消失,为了使得对应让(a + b) = c也不合法,便将重载完的函数返回类型加上const变为const sett operator+(const sett &a,const sett& b)

但对于=赋值运算符而言,(a = b) = c是可以的,我们sett operator=(const sett& another)的返回类型便不加const

所以运算符的重载不能改变语义

同理对于+=运算符而言,a+=b+=c是可以的,同样的sett operator+=(const sett& another);或者sett operator+=(const sett& a ,const sett& b);都是可以满足的,但是对于(a+=b)+=c,基本数据类型是可以的,是先a += b,再a += c,但是对于我们的类来说,这是不可以的,因为a += b,返回的新的a在栈上,马上就会消失,再执行a += c时a已经是之前的a了,所以要使用&,使得a的变化被接收到,改为sett &operator+=(const sett& another);或者sett& operator+=(const sett& a ,const sett& b);

更深层次的理解:

如果 operator+ 返回的是非 const 对象,那么表达式 (a + b) 返回的临时对象是可修改的,因此 (a + b) = c 将被视为合法的赋值操作。但这并不符合内置类型(C++ 语言本身提供的基本数据类型)的语义,因为内置类型的加法运算通常返回一个右值(不允许对其赋值)。为防止这种情况,我们通常将 operator+ 的返回类型声明为 const,这样返回的临时对象就变成 const,(a + b) = c 就会因为尝试修改一个 const 对象而编译错误,从而符合预期的语义。

相关文章:

C++回顾 Day5

自实现string完整版 my_string.h using namespace std; class mystr{public://mystr();mystr(const char * new_str nullptr);mystr(const mystr & another);char * c_str();~mystr();mystr& operator(const mystr & another);mystr operator(const mystr &…...

OpenMVS 的编译与运行

Title: OpenMVS 的编译与运行 文章目录 I. 编译与准备1. 获得源码2. wiki3. 退出 Conda 环境4. 编译5. 数据准备 II. 命令了解1. 稠密重建 DensifyPointCloud2. 曲面重建 ReconstructMesh3. 网格优化 RefineMesh4. 纹理贴图 TextureMesh III. 命令运行1. 运行稠密重建2. 运行网…...

@Transactional注解的使用

目录 一.介绍 1.使用Transactional注解的位置 2.Transactional注解的作用 二.举例 1.需求场景 2.做法 3.效果展示 三.简单总结 一.介绍 1.使用Transactional注解的位置 我们在Java开发中&#xff0c;一般在service层的方法上&#xff0c;使用Transactional注解&#x…...

路由器NAT回流踩坑

路由器 H3C GR-3000AX-U 不支持NAT回流 核心问题定位 外网访问 ✅ 非Docker服务&#xff08;直接运行在宿主机上的服务&#xff09;可以访问❌ Docker服务 无法访问 内网访问 ✅ 内网IP访问&#xff08;无论Docker还是非Docker&#xff09;正常❌ 内网通过公网IP访问 全部失败…...

如何创建RDD

创建RDD&#xff08;Resilient Distributed Dataset&#xff09;主要有以下三种方法&#xff1a; 1. 从集合创建RDD 通过将本地集合&#xff08;如列表、数组&#xff09;传递给SparkContext的parallelize方法&#xff0c;可以将本地数据转换为RDD。这种方式通常用于测试或开…...

PTS-G5K13M RF Generator 5kW / 13MHz 射频电源User s Manual

PTS-G5K13M RF Generator 5kW / 13MHz 射频电源User s Manual...

vue3父组件调用子组件方法

需求&#xff1a;在vue3中需要在父组件调用子组件的方法 思路&#xff1a;通过ref和defineExpose直接暴露给父组件 1.子组件暴露表单验证方法 <template><a-form ref"formRef" :model"formState" :rules"rules"><a-form-item …...

Python小酷库系列:5个常用的dict属性化访问扩展库

5个常用的dict属性化访问扩展库 嵌套结构高级功能性能综合建议 在前面我们详细讲解了 Box和 Munch这两个dict属性化访问的扩展库&#xff0c;总体而言它们主要用于提升配置文件数据、JSON对象数据的可读性&#xff0c;减少了代码中双引号。在这一领域中还有dotmap、addict 和…...

day009-用户管理专题

文章目录 1. 创建包含时间的文件2. 与用户相关的文件3. 用户分类4. 与用户相关的命令4.1 添加用户4.2 删除用户4.3 查看用户4.4 修改用户密码 5. sudo6. 思维导图7. 老男孩思想-学习方法 1. 创建包含时间的文件 或$()是替换符号&#xff0c;可以将命令的结果作为字符串或变量的…...

微信小程序pinia的应用

情景&#xff1a;院校列表的关注状态的实时更新 新建一个ts文件存储关注状态&#xff0c;用于集中管理用户“已关注院校”的相关状态和操作 import {definStore} from pinia; import type { College_records } from /types/university;export const useFocusCollegeStore de…...

LWIP的超时事件笔记

那个马蜂佬&#xff0c;刚发就给我两个赞 lwIP超时事件处理简介 为每个与外界网络连接的任务都设定了timeout属性&#xff0c;即等待超时时间&#xff0c;例如TCP建立连接超时、ARP缓存表项的时间管理等&#xff0c;都需要超时操作来处理 lwIP超时事件机制 一共有四种 2.1&a…...

如何避免项目结束后知识流失

避免项目结束后知识流失的方法包括&#xff1a;建立项目知识库、实施定期知识回顾与总结、强化团队内部知识共享机制、利用合适的知识管理工具。项目知识库的建设尤其关键&#xff0c;它可帮助团队保留核心经验和方法&#xff0c;确保知识沉淀在组织内部。通过知识库&#xff0…...

【MCP】客户端配置(ollama安装、qwen2.5:0.5b模型安装、cherry-studio安装配置)

【MCP】客户端配置&#xff08;ollama安装、qwen2.5:0.5b模型安装、cherry-studio安装配置&#xff09; 客户端配置&#xff08;1&#xff09;下载安装ollama&#xff08;2&#xff09;安装qwen2.5:0.5b模型&#xff08;3&#xff09;安装配置cherry-studio 客户端配置 &#…...

Media3 中 Window 的时间相关属性详解

AndroidX Media3 的 Timeline.Window 类中&#xff0c;与时间相关的属性描述了媒体播放窗口&#xff08;window&#xff09;在时间维度上的关键信息。这些属性帮助开发者理解媒体的播放范围、起始点、持续时间以及与设备时间或直播流的同步关系。 Timeline.Window 的时间相关属…...

C 语言编码规范

在 C 语言开发过程中&#xff0c;遵循编码规范不仅能提高代码的可读性、可维护性&#xff0c;还能减少潜在的错误&#xff0c;提升团队协作效率。以下从多个维度详细阐述 C 语言编码过程中需要注意的规范要点。 一、命名规范 变量命名 变量命名应做到见名知意&#xff0c;采用…...

嵌入式开发学习日志Day15

一、指针指向字符型数组 &#xff08;1&#xff09;【const】&#xff1a;在指针变量中使用时&#xff0c;无法通过该指针修改被指向的变量&#xff1b; &#xff08;2&#xff09;【const】&#xff1a;关键字&#xff0c;在C和C中&#xff0c;能加就加&#xff0c;加了一定…...

从人脸扫描到实时驱动,超写实数字分身技术解析

在元宇宙浪潮中&#xff0c;数字人、虚拟数字人等新兴概念逐渐走进大众视野&#xff0c;其中数字分身作为虚拟数字人的细分领域&#xff0c;正引发广泛关注。数字分身依托人工智能与虚拟现实技术&#xff0c;能基于真人信息进行1:1复刻&#xff0c;具备与真人高度相似的外貌、声…...

Vue3 自定义指令的原理,以及应用

文章目录 前言一、原理说明二、注册与使用1. 全局注册2. 局部注册3. 使用方式 三、典型应用场景四、案例&#xff1a;权限控制指令五、注意事项 v-draggable✅ 目标效果&#xff1a;&#x1f9e9; 1. 自定义指令定义&#x1f9f1; 2. 在项目中注册&#x1f9ea; 3. 使用示例&am…...

306.检查是否所有A都在B之前

2124. 检查是否所有 A 都在 B 之前 - 力扣&#xff08;LeetCode&#xff09; class Solution {public boolean checkString(String s) {return !s.contains("ba");} } class Solution(object):def checkString(self, s):return s.find("ba")-1...

适合java程序员的Kafka消息中间件实战

创作的初心&#xff1a; 我们在学习kafka时&#xff0c;都是基于大数据的开发而进行的讲解&#xff0c;这篇文章为java程序员为核心&#xff0c;助力大家掌握kafka实现。 什么是kafka: 历史&#xff1a; 诞生与开源&#xff08;2010 - 2011 年&#xff09; 2010 年&#xf…...

当体育数据API遇上WebSocket:一场技术互补的「攻防战」

在世界杯决赛的最后一分钟&#xff0c;你正通过手机观看直播。突然&#xff0c;解说员大喊“球进了&#xff01;”&#xff0c;但你的屏幕却卡在对方半场的回放画面——这种「延迟乌龙」的尴尬&#xff0c;正是实时体育应用面临的终极挑战。 在体育数字化浪潮下&#xff0c;用…...

1:点云处理—三种显示方法(自建点云)

1.彩色显示 *读取三维点云 dev_get_window(WindowHandle)dev_open_window(0, 0, 512, 512, black, WindowHandle1) read_object_model_3d(./19-12-26/t.ply, m, [], [], ObjectModel3D, Status)Instructions[0] : Rotate: Left button Instructions[1] : Zoom: Shift left…...

SCADA|KingSCADA运行报错:加载实时库服务失败

哈喽,你好啊,我是雷工! 最近在绵阳出差,在现场调试时遇到报错问题,翻了下以往记录没有该错误的相关笔记。 于是将问题过程及处理办法记录下来。 01 问题描述 昨天还好好的,可以正常运行的程序今天再次运行时报错: “加载 实时库服务 失败” 查看日志中错误信息如下: …...

k8s | Kubernetes 服务暴露:NodePort、Ingress 与 YAML 配置详解

CodingTechWork 引言 在 Kubernetes 集群中&#xff0c;服务暴露是将集群内部的服务对外部网络提供访问的关键环节。NodePort 和 Ingress 是两种常用的服务暴露方式&#xff0c;它们各有特点和适用场景。本文将详细介绍这两种方式的原理、配置方法以及如何通过 YAML 文件实现服…...

upload-labs靶场通关详解:第一关

一、一句话木马准备 新建一个文本文档&#xff0c;写入php代码&#xff0c;修改文件后缀名为php&#xff0c;保存。 phpinfo() 是 PHP 里的一个内置函数&#xff0c;其功能是输出关于当前 PHP 环境的详细信息。这些信息涵盖 PHP 版本、服务器配置、编译选项、PHP 扩展、环境变…...

SSA-CNN+NSGAII+熵权TOPSIS,附相关气泡图!

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 经典麻雀搜索算法深度学习多目标优化多属性决策&#xff01;SSA-CNNNSGAII熵权TOPSIS&#xff0c;附相关气泡图&#xff01;本文旨在通过优化卷积神经网络&#xff08;CNN&#xff09;以及采用NSGAII多目标优化与熵权…...

数据结构之栈与队列

一&#xff0c;栈和队列的区别 1、核心定义与特性 特性栈&#xff08;Stack&#xff09;队列&#xff08;Queue&#xff09;定义仅允许在栈顶&#xff08;表尾&#xff09;进行插入和删除的线性表&#xff0c;遵循 后进先出&#xff08;LIFO&#xff09;。允许在队尾插入、队…...

SSHv2 密钥交换(Key Exchange)详解

1. 算法协商 在密钥交换开始前&#xff0c;客户端和服务端会协商确定本次会话使用的算法组合。具体过程如下&#xff1a; 交换算法列表 客户端和服务端各自发送支持的算法列表&#xff0c;包括&#xff1a; 密钥交换算法&#xff08;如 diffie-hellman-group14-sha256&#xf…...

从零开始学习three.js(15):一文详解three.js中的纹理映射UV

1. UV 映射基础概念 1.1 什么是 UV 坐标&#xff1f; 在三维计算机图形学中&#xff0c;UV 坐标是将二维纹理映射到三维模型表面的坐标系统。UV 中的 U 和 V 分别代表2D纹理空间的水平&#xff08;X&#xff09;和垂直&#xff08;Y&#xff09;坐标轴&#xff0c;与三维空间…...

解锁 Postgres 扩展日!与瀚高共探 C/Java 跨语言扩展技术的边界与未来

2025 年 5 月 13 日至 16 日&#xff08;蒙特利尔时间&#xff09;&#xff0c;一年一度的 PostgreSQL 开发者大会 PGConf.dev&#xff08;原 PGCON 会议&#xff09;将在加拿大蒙特利尔盛大举行。同去年一样&#xff0c;在本次大会开幕的前一天同样会举办另外一个专场活动——…...

【Hive入门】Hive增量数据导入:基于Sqoop的关系型数据库同步方案深度解析

目录 引言 1 增量数据导入概述 1.1 增量同步与全量同步对比 1.2 增量同步技术选型矩阵 2 Sqoop增量导入原理剖析 2.1 Sqoop架构设计 2.2 增量同步核心机制 3 Sqoop增量模式详解 3.1 append模式&#xff08;基于自增ID&#xff09; 3.2 lastmodified模式&#xff08;基…...

✍️【TS类型体操进阶】挑战类型极限,成为类型魔法师!♂️✨

哈喽类型战士们&#xff01;今天我们要玩转TS类型体操&#xff0c;让你的类型系统像体操运动员一样灵活优雅~ 学会这些绝招&#xff0c;保准你的代码类型稳如老狗&#xff01;&#xff08;文末附类型体操段位表&#xff09;&#x1f680; 一、什么是类型体操&#xff1f; &…...

部署Prometheus+Grafana简介、监控及设置告警(一)

部署PrometheusGrafana简介、监控及设置告警 一. 环境准备 服务器类型IP地址组件 Prometheus服务器、agent服务器、Grafana服务器192.168.213.7Prometheus 、node_expprter&#xff0c;Grafanaagent服务器192.168.213.8node_exporter 如果有防火请记得开启9090&am…...

k8s部署OpenELB

k8s部署OpenELB k8s部署OpenELB配置示例: layer2模式 k8s部署OpenELB 部署OpenELB至K8s集群 # k8s部署OpenELB kubectl apply -f https://raw.githubusercontent.com/openelb/openelb/refs/heads/master/deploy/openelb.yaml# 查看openelb的pod状态 kubectl get pods -n open…...

python打卡day18

聚类后的分析&#xff1a;推断簇的类型 知识点回顾&#xff1a; 推断簇含义的2个思路&#xff1a;先选特征和后选特征通过可视化图形借助ai定义簇的含义科研逻辑闭环:通过精度判断特征工程价值 作业&#xff1a;参考示例代码对心脏病数据集采取类似操作&#xff0c;并且评估特征…...

新品发布 | 96MHz主频 M0+内核低功耗单片机CW32L011产品介绍

CW32L011是基于 eflash 的单芯片低功耗微控制器&#xff0c;集成了主频高达 96MHz的 ARMCortex-M0内核、高速嵌入式存储器(多至 64K字节 FLASH 和多至 6K 字节 SRAM)以及一系列全面的增强型外设和 I/O 口。 所有型号都提供全套的通信接口(3路 UART、1路 SPI和1路12C)、12位高速…...

【面试 · 二】JS个别重点整理

目录 数组方法 字符串方法 遍历 es6 构造函数及原型 原型链 this指向 修改 vue事件循环Event Loop FormData 数组方法 改变原数组&#xff1a;push、pop、shift、unshift、sort、splice、reverse不改变原属组&#xff1a;concat、join、map、forEach、filter、slice …...

【详细教程】ROC曲线的计算方式与绘制方法详细介绍

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

【神经网络与深度学习】VAE 在解码前进行重参数化

在 VAE 中&#xff0c;解码之前进行重参数化主要有以下几个重要原因&#xff1a; 可微分性 在深度学习里&#xff0c;模型是通过反向传播算法来学习的&#xff0c;而这需要计算梯度。若直接从潜在变量的分布 (q_{\theta}(z|x))&#xff08;由编码器输出的均值 (\mu) 和方差 (…...

ai agent(智能体)开发 python3基础11: java 调用python waitfor卡死,导致深入理解操作系统进程模型和IPC机制

java 调用python waitfor 卡死 导致浏览器无法自动关闭&#xff0c;java &#xff0c;python双发无限等待 根源在于还是没有理解 进程之间标准输入输出到底是什么含义 系统进程与跨语言调用的核心机制 在跨语言调用&#xff08;如Java调用Python&#xff09;时&#xff0c;理…...

大模型赋能:2D 写实数字人开启实时交互新时代

在数字化浪潮席卷全球的当下&#xff0c;人工智能技术不断突破创新&#xff0c;其中大模型驱动的 2D 写实数字人正成为实时交互领域的一颗新星&#xff0c;引领着行业变革&#xff0c;为人们带来前所未有的交互体验。 一、2D 写实数字人概述 2D 写实数字人是通过计算机图形学…...

CATIA高效工作指南——零件建模篇(二)

一、PowerCopy特征复用技术 1.1 智能特征封装 通过​​几何图形集(Geometrical Set)​​构建参数化特征组&#xff0c;将关联的草图、曲面、实体等元素进行逻辑封装。操作流程如下&#xff1a; 创建新几何图形集并完成特征建模激活PowerCopy命令&#xff0c;选择目标几何集定…...

QT人工智能篇-opencv

第一章 认识opencv 1. 简单概述 OpenCV是一个跨平台的开源的计算机视觉库&#xff0c;主要用于实时图像处理和计算机视觉应用‌。它提供了丰富的函数和算法&#xff0c;用于图像和视频的采集、处理、分析和显示。OpenCV支持多种编程语言&#xff0c;包括C、Python、Java等&…...

java实现一个操作日志模块功能,怎么设计

为了设计一个高效、可靠且可扩展的操作日志模块&#xff0c;可以结合 ​AOP&#xff08;面向切面编程&#xff09;​、异步处理​&#xff08;多线程或MQ&#xff09;以及合理的存储策略&#xff0c;具体方案如下&#xff1a; ​1. 技术选型与架构设计​ ​​(1) AOP 实现非侵…...

音频相关基础知识

主要参考&#xff1a; 音频基本概念_音频和音调的关系-CSDN博客 音频相关基础知识&#xff08;采样率、位深度、通道数、PCM、AAC&#xff09;_音频2通道和8ch的区别-CSDN博客 概述 声音的本质 声音的本质是波在介质中的传播现象&#xff0c;声波的本质是一种波&#xff0c;是一…...

【Agent】使用 Python 结合 OpenAI 的 API 实现一个支持 Function Call 的程序,修改本机的 txt 文件

使用 Python 结合 OpenAI 的 API 来实现一个支持 Function Call 的程序&#xff0c;修改本机的 txt 文件。需要注意&#xff0c;在运行代码前&#xff0c;要确保已经安装了 openai 库&#xff0c;并且拥有有效的 OpenAI API Key。 import openai import os# 设置你的 OpenAI A…...

mint系统详解详细解释

Linux Mint是一款基于Ubuntu的开源桌面操作系统&#xff0c;以用户友好、稳定性强、功能全面著称&#xff0c;尤其适合从Windows迁移的新手和追求高效办公的用户。以下从技术架构、版本演进、生态体系、核心功能、应用场景等维度进行深度解析&#xff1a; 一、技术架构&#x…...

WordPress个人博客搭建(三):WordPress网站优化

前言 在之前的WordPress个人博客搭建&#xff08;一&#xff09;与WordPress个人博客搭建&#xff08;二&#xff09;文章中&#xff0c;我们已经在自己的非凡云云服务器上成功搭建了WordPress个人博客。现在让我们继续这场数字世界的耕耘&#xff0c;通过插件与主题的巧妙搭配…...

力扣1812题解

记录 2025.5.7 题目&#xff1a; 思路&#xff1a; 从左下角开始&#xff0c;棋盘的行数和列数&#xff08;均从 1 开始计数&#xff09;之和如果为奇数&#xff0c;则为白色格子&#xff0c;如果和为偶数&#xff0c;则为黑色格子。 代码&#xff1a; class Solution {pu…...

深入理解XGBoost(何龙 著)学习笔记(三)

原创 化心为海 微阅读札记https://mp.weixin.qq.com/s/vBE3fu9AZDjRFd5niJU0lg 2025年05月06日 18:17 北京 第三章 机器学习算法基础 摘要&#xff1a;本章首先介绍了基础的机器学习算法的实现原理和应用&#xff1b;然后对决策树模型做了详细介绍&#xff1b;最后&#xff0…...