c++中的常用知识点总结

命名空间

使用命名空间之后,调用代码时可以省去也可以不省去相关的前缀。

#include <iostream>using namespace std;//使用c++自己的命名空间
int main() {int num1 = 10;std::cout << "Hello, World!" << std::endl;cout<<num1<<endl;return 0;
}

自定义命名空间

// 命名空间#include <iostream>// 声明std,我们的main函数就可以直接使用里面的成员,不需要使用 std::
using namespace std; // C++自己的命名空间 (C# .net 命名空间)// 自定义命名空间
namespace derry1 {int age = 33;char * name = "Derry猛男1";void show() {cout << "name:" << name << ", age:" << age << endl;}void action() {cout << "derry1 action" << endl;}
}// TODO ------ 命名空间里面重复的函数
// 自定义命名空间
namespace derry2 {void action() {cout << "derry2 action" << endl;}
}// TODO ------ 小概率会遇到的情况,命名空间的嵌套
// 自定义命名空间
namespace derry3 {namespace derry3Inner {namespace derry3Inner1 {namespace derry3Inner2 {namespace derry3Inner3 {void out() {cout << "爱恨情仇人消瘦,悲欢起落人寂寞" << endl;}}}}}
}// 声明各个写的 命名空间
// using namespace derry1;int main() {cout << "命名空间" << endl;// 声明各个写的 命名空间using namespace derry1;int ageValue = derry1::age; // 方式1 使用 刚刚声明的命名空间derry1::show(); // 使用 刚刚声明的命名空间ageValue = age; // 方式2 直接去引出来 ::show(); // 直接去引出来 ::// TODO ------ 命名空间里面重复的函数using namespace derry2;// action(); 很尴尬derry1::action();derry2::action();// TODO ------ 小概率会遇到的情况,命名空间的嵌套// 第一种方式 先声明命名空间  再使用using namespace derry3::derry3Inner::derry3Inner1::derry3Inner2::derry3Inner3;// 再使用out();// 第二种方式 直接使用derry3::derry3Inner::derry3Inner1::derry3Inner2::derry3Inner3::out();return 0;
}

  • 头文件:Student.h
//
// Created by sunteng on 2023/9/5.
//#ifndef TEST_STUDENT_H
#define TEST_STUDENT_H#endif //TEST_STUDENT_Hclass Student{private://下面的成员和函数,都是私有char * name;int age;public://下面的成员和函数,都是公有void setAge(int age);void setName(char *name);int getAge();char * getName();};
  • 类文件:Student.cpp
//
// Created by sunteng on 2023/9/5.
//#include "Student.h"// 根据 Student.h 头文件 ,写实现// 和实现头文件那个函数,没有任何关系,相当于另外一个函数
/*void setAge(int age) {}*/void Student::setAge(int age) {//this是一个Student类型的指针this->age = age;
}void Student::setName(char *name) {this->name = name;
}int Student::getAge() {return this->age;
}char * Student::getName() {return this->name;
}
  • main
#include <iostream>
#include "Student.h"//引入头文件即可
using namespace std;
int main() {Student student1;//栈区开辟空间//赋值student1.setName("brett");student1.setAge(19);cout<<"name:"<<student1.getName()<<" ,age:"<<student1.getAge()<<endl;Student* student2 = new Student();//new 堆区分配空间student2->setAge(88);student2->setName("mike");cout<<"name:"<<student2->getName()<<" ,age:"<<student2->getAge()<<endl;//堆区分配的对象使用完之后必须手动释放if(student2){delete student2;student2 = NULL;}// new/delete 是一套  会调用构造函数 与 析构函数   【C++标准规范】// malloc/free是一套  不调用构造函数 与 析构函数 【C的范畴,虽然不推荐,但是也是可以的】return 0;
}
  • 构造函数和析构函数

#include <iostream>
#include <string.h>
using namespace std;class Student {// 构造函数
public:// 空参数构造函数Student() {cout << "空参数构造函数" << endl;}// 一个参数的构造函数// :Student(name, 87) 等价 1.调用两个参数的构造函数, 2.再调用当前函数// 学生说的:先调用两个参数的,再调用一个的Student(char *name) :Student(name, 87) {cout << "一个参数的构造函数" << endl;if(!this->name){//防止重复赋值this->name = name;}}// 两个参数的构造函数Student(char *name, int age) {// this->name = name;// 堆区this->name = (char *) (malloc(sizeof(char *) * 10));strcpy(this->name, name);this->age = age;cout << "两个参数的构造函数" << endl;}// 析构函数 Student对象的,临终遗言,Student对象被回收了,你做一些释放工作// delete stu 的时候,我们的析构函数一定执行// free不会执行析构函数,也意味着,你没法在析构函数里面,做释放工作, malloc也不会调用构造函数~Student() {cout << "析构函数" << endl;// 必须释放 堆区开辟的成员if (this->name) {free(this->name);this->name = NULL; // 执行NULL的地址,避免出现悬空指针}}// 私有属性
private:char *name;int age;// 公开的 set get 函数
public:int getAge() {return this->age;}char *getName() {return this->name;}void setAge(int age) {this->age = age;}void setName(char *name) {this->name = name;}
};int main() {// TODO =========== 下面是堆区 开辟空间的  堆区必须手动释放,否则内存占用越来// 系统源码中,会看到,很多使用 new 关键字// *stu  ->:调用一级指针的成员// new/delete// C++中,必须使用 new/delete 一套Student *stu = new Student("杜子腾");cout << "name:" << stu->getName() << ", age:" << stu->getAge() <<  endl;delete stu;return 0;
}
  • 拷贝构造函数与构造函数
// 4.拷贝构造函数。#include <iostream>
#include <string.h>using namespace std;class Student {public:Student() { cout << "空参数构造函数" << endl; }// 两个参数的构造函数Student(char *name, int age) : name(name), age(age) {cout << "两个参数构造函数" << endl;}// 析构函数// ~Student(char * name) { } 这样写,就不是析构函数了,如果你这样写,C/C++编译器对你很无语~Student() {cout << "析构函数" << endl;}// 拷贝构造函数,它默认有,我们看不到,一旦我们写拷贝构造函数,会覆盖她// 对象1 = 对象2// 覆盖拷贝构造函数Student(const Student & student) { // 常量引用:只读的,不让你修改cout << "拷贝构造函数" << endl;// 我们自己赋值// 为什么要自己赋值,自己来控制,就可以 例如:-10this->name = student.name;this->age = student.age - 10;cout << "自定义拷贝构造函数 内存地址 " << &student << endl;}// 私有属性
private:char *name;int age;// 公开的 set get 函数
public:int getAge() {return this->age;}char *getName() {return this->name;}void setAge(int age) {this->age = age;}void setName(char *name) {this->name = name;}
};struct Person {int age;char *name;
};// TODO = 号的意义 隐士代码,引出 拷贝构造函数int main() {Person person1 = {100, "张三丰"};// = 你看起来,没有什么特殊,隐士的代码:你看不到  C/C++编译器 会把p1的成员值赋值给p2成员Person person2 = person1;cout << &person1 << endl;cout << &person2 << endl;cout << person2.name << ",  " << person2.age << endl;// 思考:对象 对象1=对象2  默认的 拷贝构造函数return 0;
}// TODO  拷贝构造函数/*int main() {Student stu1("李鬼", 34);Student stu2 = stu1;cout << stu2.getName() << " , " <<  stu2.getAge() <<  endl;cout << "main " << &stu1 << endl; // 地址的打印是一样的,  注意:cnetos的环境 地址打印有差异,要注意// TODO  拷贝构造函数的注意点:// Student stu1("李鬼", 34);// Student stu2;// stu2 = stu1; // 这样赋值是不会调用 自定义拷贝构造函数,但是会调用默认赋值// Student stu2 = stu1;  // 这样赋值是会调用 自定义拷贝构造函数,我们自己赋值// cout << stu2.getName() << " , " <<  stu2.getAge() <<  endl;getchar(); // 程序等待在这一行return 0;
} // main函数弹,stu1栈成员会回收  stu2栈成员会回收
*/// TODO 这种写法 拷贝构造函数  到底会不会调用
/*int main() {Student *student1 = new Student("杜子腾", 39);Student *student2 = student1;  // 压根就不会执行拷贝构造函数(指针指向问题,和我们刚刚那个  对象2=对象1 是两回事)student2->setAge(99);cout << student1->getName() << student1->getAge() << endl;return 0;
}*/
  • 深拷贝与浅拷贝
#define _CRT_SECURE_NO_WARNINGS // strcpy运行会报错,支持#include<iostream>
#include<string.h>
using namespace std;class Student
{
public:int age;char * name;Student() { cout << "空参数构造函数" << endl; }Student(char * name) :Student(name, 99) {cout << "一个参数构造函数 this:" << this << endl;}Student(char * name, int age) {cout << "二个参数构造函数 this:" << this << endl;this->name = (char *)malloc(sizeof(char *)* 10);strcpy(this->name, name);this->age = age;}~Student() {cout << "析构函数执行 &this->name:" << this->name << endl;free(this->name);this->name = NULL;}// 默认有一个拷贝构造函数 隐士的 我们看不见// 一旦复写了拷贝构造函数,默认的还在吗? Java的构造函数一个思路// 自定义拷贝构造函数 如果有堆成员,必须采用深拷贝Student(const Student & stu) {// stu 旧地址// this 新地址// s2 = 新地址cout << "拷贝构造函数 &stu:" << &stu << " this:" << this << endl;//二者地址不一样// 【浅拷贝】:新地址name  旧地址name 指向同一个空间,会造成,重复free的问题,引发奔溃// 新地址name = 旧地址 (浅拷贝)// this->name = stu.name;// 【深拷贝】this->name = (char *)malloc(sizeof(char *)* 10);strcpy(this->name, name);this->age = stu.age;cout << "拷贝构造函数2 this->name:" << (this->name) << "  stu.name:" << stu.name << endl;// 深拷贝 后面见  原理全部打通的时候讲} // 此拷贝构造函数执行完 旧会出现一个 this==新地址  给 main函数的 stu// 默认的拷贝构造函数 是浅拷贝
};void showStudent(Student stu) {cout << "showStudent函数:" << &stu << "  " << stu.name << "," << stu.age<< endl;
}int main() {Student stu("刘奋", 31);showStudent(stu); // 弹栈后 新地址name释放一遍showStudent(stu);
//
//    showStudent(stu);
//
//
//    showStudent(stu);
//
//
//    showStudent(stu);getchar();return 0;
} // main函数弹栈 stu 旧地址

指针常量 常量指针 常量指针常量

// 指针常量 常量指针 常量指针常量#include <iostream>
#include <string.h>
#include <string.h>using namespace std;int main() {// *strcpy (char *__restrict, const char *__restrict);// strcpy()int number = 9;int number2 = 8;// 大道至简 一分钟搞定// 常量指针const int * numberP1 = &number;// *numberP1 = 100; // 报错,不允许去修改【常量指针】存放地址所对应的值// numberP1 = &number2; // OK,允许重新指向【常量指针】存放的地址//  指针常量int* const numberP2 = &number;*numberP2 = 100; // OK,允许去修改【指针常量】存放地址所对应的值// numberP2 = &number2; // 报错,不允许重新指向【指针常量】存放的地址// 常量指针常量const int * const numberP3 = &number;// *numberP3 = 100; // 报错,不允许去修改【常量指针常量】存放地址所对应的值// numberP3 = &number2; // 报错,不允许重新指向【常量指针常量】存放的地址return 0;
}

运算符重载

// 2.类里运算符重载。#include <iostream>
using namespace std;class Derry {
private:int x,y;public:Derry() {}// 系统C++源码,大量使用此方式 :x(x), y(y)Derry(int x, int y) :x(x), y(y) {}// set get 函数void setX(int x) {this->x = x;}void setY(int y) {this->y = y;}int getX() {// this->x  -9; 系统怕你在函数里面 修改了return this->x;}int getY() {return this->y;}// +号,运算符重载/*Derry operator + (Derry derry1) {// this指针 指向当前对象,所以只需要一个int x = this->x + derry1.getX();int y = this->y + derry1.getY();return Derry(x, y);}*/// 系统是这样写的  常量引用:不允许修改,只读模式// const 关键字的解释// & 性能的提高,如果没有&  运行+ 构建新的副本,会浪费性能// 如果增加了& 引用是给这块内存空间取一个别名而已Derry operator + (const Derry& derry1) {// this指针 指向当前对象,所以只需要一个int x = this->x + derry1.x; // 我在类的里面,是可以拿私有成员的int y = this->y + derry1.y; // 我在类的里面,是可以拿私有成员的return Derry(x, y);}// 运算符- 重载Derry operator - (const Derry & derry1) {int x = this->x - derry1.x;int y = this->y - derry1.y;return Derry(x, y);}
};int main() {Derry derry1(1000, 2000);Derry derry2(3000, 4000);// Derry result = derry1 + derry2;Derry result = derry2 - derry1;cout << result.getX() << " , " << result.getY() << endl;return 0;
}

二义性与虚基类

// 多继承 二义性2:
// 在真实开发过程中,严格避免出现 二义性#include <iostream>using namespace std;// 祖父类
class Object {
public:int number;
};// 父类1
class BaseActivity1 : public Object {};// 父类2
class BaseActivity2 : public Object {};// 子类
class Son : public BaseActivity1, public BaseActivity2 {// 第二种解决方案: 在类中定义同名成员,覆盖掉父类的相关成员
public:int number;};int main() {Son son;// error: request for member 'show' is ambiguous  二义性 歧义// son.number = 2000;// 第一种解决方案: :: 明确指定son.BaseActivity1::number  = 1000;son.BaseActivity2::number  = 1000;// 第二种解决方案: 在类中定义同名成员,覆盖掉父类的相关成员son.number = 3000;// 第三种解决方案: 【虚基类】 属于 虚继承的范畴return 0;
}//第三种方式;虚基类// 第三种解决方案: 【虚基类】 属于 虚继承的范畴
// 真实C++开始,是很少出现,二义性(歧义) 如果出现, 系统源码(系统用 第三种解决方案)#include <iostream>using namespace std;// 祖父类
class Object{
public:int number;void show() {cout << "Object show run..." << endl;}
};// 父类1
class BaseActivity1 : virtual public Object {
};// 父类2
class BaseActivity2 : virtual public Object {
};// 子类
class Son : public BaseActivity1, public BaseActivity2 {};int main() {Object object;BaseActivity1 baseActivity1;BaseActivity2 baseActivity2;Son son;object.number = 100;baseActivity1.number = 200;baseActivity2.number = 300;son.number = 400;object.show();baseActivity1.show();baseActivity2.show();son.show();cout << object.number << endl;cout << baseActivity1.number << endl;cout << baseActivity2.number << endl;cout << son.number << endl;return 0;
}
  • 虚基类

在C++中,虚基类是用于解决多继承中的菱形继承问题的一种机制。菱形继承指的是一个派生类同时继承自两个或多个基类,而这些基类又共同继承自同一个基类,形成了一个菱形的继承结构。

虚基类的作用是解决菱形继承带来的二义性和冗余的问题。当一个派生类通过多条路径继承自同一个基类时,如果不使用虚基类,那么在派生类中就会存在多个基类子对象的实例,这样就会导致同名成员在派生类中出现冗余,访问这些成员时会产生二义性。

通过使用虚基类,可以确保在派生类中只有一个基类子对象的实例,从而避免了冗余和二义性。虚基类的成员在派生类中只有一份拷贝,这样就可以确保派生类对基类成员的访问是唯一的。

使用虚基类的语法是在派生类的基类列表中,将虚基类声明为虚基类。例如:

class Base {
public:// Base类的成员
};class Derived1 : virtual public Base {
public:// Derived1类的成员
};class Derived2 : virtual public Base {
public:// Derived2类的成员
};class Derived3 : public Derived1, public Derived2 {
public:// Derived3类的成员
};

在上面的例子中,Base是虚基类,Derived1和Derived2都通过虚继承方式继承自Base。Derived3通过多继承同时继承自Derived1和Derived2,这样就避免了菱形继承带来的问题。

总结来说,虚基类的作用是解决多继承中的菱形继承问题,避免冗余和二义性,确保派生类对基类成员的访问是唯一的。

公有继承与私有继承


#include <iostream>using namespace std;class Person {
public:char *name;int age;public:Person(char *name, int age) : name(name) {this->age = age;cout << "Person 构造函数" << endl;}void print() {cout << this->name << " , " << this->age << endl;}
};// 1.默认是 隐式代码: : private Person
// 2.私有继承:在子类里面是可以访问父类的成员,但是在类的外面不行
// 3.必须公开继承,才可以访问父类的成员
class Student : public Person {// 类 默认是私有,注意下private:char * course;public:// :父类 , 给自己子类成员初始化Student(char * name, int age, char* course) : Person(name, age) , course(course) {cout << "Student 构造函数" << endl;}void test() {cout << name << endl;cout << age << endl;print();}
};int main() {Student stu("李元霸", 99, "C++");// 公开继承,才可以拿父类的成员stu.name = "李四";return 0;
}

静态类

// 2.C++static关键字。 正确的写法/*** 静态的总结:* 1.可以直接通过类名::静态成员(字段/函数)* 2.静态的属性必须要初始化,然后再实现(规则)* 3.静态的函数只能取操作静态的属性和方法*/#include <iostream>using namespace std;class Dog {
public:char * info;int age;// 先声明static int id;static void update() {id += 100;// 报错:静态函数不能调用非静态函数// update2();}void update2() {id = 13;}
};// 再实现
int Dog::id = 9;int main() {Dog dog;dog.update2(); // 普通函数Dog::update(); // 静态函数dog.update(); // 对象名.静态函数(一般都是使用::调用静态成员,这种方式可以 知道就行)cout << Dog::id << endl;return 0;
}

友元类和友元函数

在C++中,友元类和友元函数是一种特殊的访问权限控制机制,允许一个类或函数访问另一个类的私有成员。

友元类(Friend Class)是指在一个类中声明另一个类为友元,从而使得被声明的类可以访问声明它为友元的类的私有成员。友元类的声明通常出现在类的定义中,例如:

class A {friend class B; // B是A的友元类
private:int privateData;
};class B {
public:void accessPrivateData(A& obj) {int data = obj.privateData; // 可以访问A类的私有成员}
};

在上面的例子中,类B被声明为类A的友元类,因此类B可以访问类A的私有成员privateData。

友元函数(Friend Function)是指在一个类中声明一个函数为友元,从而使得被声明的函数可以访问声明它为友元的类的私有成员。友元函数的声明通常出现在类的定义中,例如:

class A {friend void printPrivateData(A& obj); // printPrivateData是A的友元函数
private:int privateData;
};void printPrivateData(A& obj) {int data = obj.privateData; // 可以访问A类的私有成员
}

在上面的例子中,函数printPrivateData被声明为类A的友元函数,因此函数printPrivateData可以访问类A的私有成员privateData。

需要注意的是,友元类和友元函数破坏了封装性,因此应该谨慎使用。过度使用友元可能会导致代码的可维护性和可读性下降。在设计类的时候,应该优先考虑使用成员函数和访问修饰符(如public、private、protected)来实现对类成员的访问控制。只有在确实需要访问私有成员的特殊情况下,才考虑使用友元类或友元函数。

// 友元函数// 老外:你是它的好朋友,那就可以拿私有成员给好朋友#include <iostream>using namespace std;class Person {
private: // 私有的age,外界不能访问int age = 0;public:Person(int age) {this->age = age;}int getAge() {return this->age;}// 定义友元函数 (声明,没有实现)friend void updateAge(Person * person, int age);
};// 友元函数的实现,可以访问所以私有成员
void updateAge(Person* person, int age) {// 默认情况下:不能修改 私有的age// 谁有这个权限:友元(拿到所有私有成员)person->age = age;
}int main() {Person person = Person(9);updateAge(&person, 88);cout << person.getAge() << endl;return 0;
}

可变参数

#include <iostream>
#include <stdarg.h> // 可变参数的支持
using namespace std;// Java的可变参数: int ...
// C++的可变参数写法:...// count变量的第二个用处,用于循环遍历长度
void sum(int count, ...) {va_list vp; // 可变参数的动作// 参数一:可变参数开始的动作vp// 参数二:内部需要一个 存储地址用的参考值,如果没有第二个参数,内部他无法处理存放参数信息va_start(vp, count);// 到这里后:vp就已经有丰富的信息for (int i = 0; i < count; ++i) {int r = va_arg(vp, int);cout << r << endl;}// 越界 系统值 乱码// 取出可变参数的一个值 【娶不到后,会取系统值 乱码】
//   int number  = va_arg(vp, int);
//    cout << number << endl;// 关闭阶段(规范:例如:file文件一样 要关闭)va_end(vp);
}// 1.可变参数
int main() {sum(3, 6,7,8); // 真实开发过程的写法return 0;
}

this是什么——指针常量

class Worker {
public:char * name;int age = NULL; // C++中不像Java,Java有默认值, 如果你不给默认值,那么就是系统值 -64664// int * const  指针常量 指针常量【地址对应的值能改,地址不可以修改】// const int *  常量指针 常量指针【地址可以修改,地址对应的值不能改】// 纠结:原理:为什么可以修改age// 默认持有隐士的this【类型 * const this】// 类型 * const 指针常量:代表指针地址不能被修改,但是指针地址的值是可以修改的void change1() {// 代表指针地址不能被修改// this = 0x6546;  // 编译不通过,地址不能被修改,因为是指针常量// 地址不可以修改// this = 0x43563;// 隐士的this// 但是指针地址的值是可以修改的// 地址对应的值能改this->age = 100;this->name = "JJJ";}// 默认现在:this 等价于 const Student * const  常量指针常量(地址不能改,地址对应的值不能改)void changeAction() const {// 地址不能改// this = 0x43563;// 地址对应的值不能改// this->age = 100;}// 原理:修改隐士代码  const 类型 * const 常量指针常量void showInfo() const {// this->name = "";// this->age = 88;// 只读的cout << "age:" << age << endl;}
};

多线程

C++ 11 之后添加了新的标准线程库 std::thread,std::thread 在 头文件中声明,因此使用 std::thread 时需要包含 在 头文件。

// 演示多线程的CPP程序
// 使用三个不同的可调用对象
#include <iostream>
#include <thread>
using namespace std;// 一个虚拟函数
void foo(int Z)
{for (int i = 0; i < Z; i++) {cout << "线程使用函数指针作为可调用参数\n";}
}// 可调用对象
class thread_obj {
public:void operator()(int x){for (int i = 0; i < x; i++)cout << "线程使用函数对象作为可调用参数\n";}
};int main()
{cout << "线程 1 、2 、3 ""独立运行" << endl;// 函数指针thread th1(foo, 3);//不需要显式调用start()方法来启动线程,std::thread对象的构造函数会自动启动线程的执行。// 函数对象thread th2(thread_obj(), 3);// 定义 Lambda 表达式auto f = [](int x) {for (int i = 0; i < x; i++)cout << "线程使用 lambda 表达式作为可调用参数\n";};// 线程通过使用 lambda 表达式作为可调用的参数thread th3(f, 3);// 等待线程完成// 等待线程 t1 完成th1.join();// 等待线程 t2 完成th2.join();// 等待线程 t3 完成th3.join();return 0;
}/*
线程 1 、2 、3 独立运行
线程使用函数指针作为可调用参数
线程使用函数指针作为可调用参数
线程使用函数指针作为可调用参数
线程使用函数对象作为可调用参数
线程使用函数对象作为可调用参数
线程使用函数对象作为可调用参数
线程使用 lambda 表达式作为可调用参数
线程使用 lambda 表达式作为可调用参数
线程使用 lambda 表达式作为可调用参数
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机网络】 ARP协议和DNS协议

文章目录 数据包在传输过程中的变化过程单播组播和广播ARP协议ARP代理免费ARP路由数据转发过程DNS协议 数据包在传输过程中的变化过程 在说ARP和DNS之前&#xff0c;我们需要知道数据包在传输过程的变化过程 从图片中可以看到&#xff0c;发送方的原数据最开始是在应用层&…

【元宇宙】区块链,元宇宙最大化的驱动力

如今&#xff0c;一些观察者认为区块链是在结构上实现元宇宙的必要条件&#xff0c;而其他人则认为这种说法是荒谬的。人们对于区块链技术本身仍然有很多困惑&#xff0c;所以根本谈不上清楚地了解込块链技术与元宇宙的关系。所以&#xff0c;我们可以从区块链的定义开始介绍。…

vscode使用delve调试golang程序

环境配置 delve仓库&#xff0c;含有教程&#xff1a;https://github.com/go-delve/delve golang的debugging教程&#xff1a;https://github.com/golang/vscode-go/wiki/debugging > go version go version go1.20 windows/amd64> go install github.com/go-delve/de…

华为云Stack的学习(五)

六、华为云stack服务简介 1.云服务在华为云Stack中的位置 云服务对接多个数据中心资源池层提供的资源&#xff0c;并向各种行业应用提供载体。 2.华为云Stack通用服务 2.1 云计算的服务模式 2.2 计算相关的云服务 2.3 存储相关的云服务 2.4 网络相关的云服务 3.云化案例 **…

如何取消KEIL-MDK工程中出现的CMSIS绿色图标

如何取消KEIL-MDK工程中出现的CMSIS绿色图标&#xff1f;我以前经常遇到&#xff0c;不知道怎么搞&#xff0c;好像也不影响编译结果。以前问过其他人&#xff0c;但是不知道怎么搞&#xff0c;相信很多人也遇到过。水平有限&#xff0c;表达不清楚&#xff0c;见下图&#xff…

Bootstrap的标题类(标题样式h1~h6)

Bootstrap 的标题字体大小通常遵循以下样式规则&#xff1a; h1 标题的字体大小为 2.5rem&#xff08;40像素&#xff09;。h2 标题的字体大小为 2rem&#xff08;32像素&#xff09;。h3 标题的字体大小为 1.75rem&#xff08;28像素&#xff09;。h4 标题的字体大小为 1.5re…

SOME/IP 支持两种序列化方式:TLV 和 TV

SOME/IP 是一种基于 IP 的可扩展面向服务的中间件协议,它可以在车载以太网中实现 ECU 之间的高效通信和互操作性。 SOME/IP 的序列化方式是指将数据结构或对象按照一定的规则转换成字节序列的过程,以便在网络中传输和解析。 SOME/IP 支持两种序列化方式:TLV 和 TV。 TLV是…

C++std::function和std::bind()的概念

std::function&#xff1a; 一个通用的函数封装器&#xff0c;它允许你存储和调用任何可以被调用的东西&#xff0c;例如函数、函数指针、函数对象、Lambda 表达式等。 std::bind&#xff1a; 用于创建函数对象。一个可调用对象的绑定版本&#xff0c;可以提前绑定某些参数&am…

Codeforces Round 260 (Div. 1) B. A Lot of Games(字典树+博弈)

B. A Lot of Games 链接&#xff1a;Codeforces Round 260 (Div. 1) B. A Lot of Games 题意 给定 n n n 个字符串&#xff0c;A和B准备玩一个游戏&#xff0c;每一轮有一个初始空字符串&#xff0c;每人轮流向其中添加字符&#xff0c;要求添加后的字符串必须是这 n n n …

【trie树】CF Edu12 E

Problem - E - Codeforces 题意&#xff1a; 思路&#xff1a; 这其实是一个套路题 区间异或转化成前缀异或&#xff0c;然后枚举 i 对于每一个 i&#xff0c;ai ^ x k&#xff0c;对 x 计数 先建一棵字典树&#xff0c;然后在字典树上计数 先去对 > k 的部分计数&a…

微信小程序第三方插件申请

记录下小程序申请插件的页面&#xff0c;之前自己找了很久&#xff0c;方便后续使用 1. 先找到自己需要的第三方插件的appid 2. 登录微信公众平台后台&#xff08;mp.weixin.qq.com&#xff09; 3. 打开小程序插件页面 https://mp.weixin.qq.com/wxopen/plugindevdoc?appi…

国际版阿里云/腾讯云:弹性高性能计算E-HPC入门概述

入门概述 本文介绍E-HPC的运用流程&#xff0c;帮助您快速上手运用弹性高性能核算。 下文以创立集群&#xff0c;在集群中安装GROMACS软件并运转水分子算例进行高性能核算为例&#xff0c;介绍弹性高性能核算的运用流程&#xff0c;帮助您快速上手运用弹性高性能核算。运用流程…

AI批量写文章伪原创:基于ChatGPT长文本模型,实现批量改写文章、批量回答问题(长期更新)

import traceback import openai import osopenai.api_key = ""conversation=[{"role": "system", "content": "You are a helpful assistant."}] max_history_len = 20 first_message = Nonedir = rJ:\ai\input #要改写的文…

软件设计的七大原则

一. 软件设计的七大原则 单一职责原则&#xff1a;一个类只负责一个功能领域中的饿相应职责。开闭原则&#xff1a;对扩展开放&#xff0c;对修改关闭&#xff0c;多使用抽象类和接口&#xff0c;应该尽量使这个系统能够扩展新的功能&#xff0c;通过扩展来实现变化&#xff0…

易云维®医院后勤管理系统软件利用物联网智能网关帮助实现医院设备实现智能化、信息化管理

近年来&#xff0c;我国医院逐渐意识到医院设备信息化管理的重要性&#xff0c;逐步建立医院后勤管理系统软件&#xff0c;以提高信息化管理水平。该系统是利用数据库技术&#xff0c;为医院的中央空调、洁净空调、电梯、锅炉、医疗设备等建立电子档案&#xff0c;把设备监控、…

Mysql 主从复制

简述 start slave; show slave status\G stop slave; reset slave; # delete relay log, create relay log. reset master; # delete bin log, restart.单表超过 500 万行 或 容量超过 2GB, 才推荐分库分表. 如果预计三年后的数据量根本达不到这个级别, 请不要在创建表时就分库…

性能炸裂c++20协程+iocp/epoll,超轻量高性能异步库开发实战

前言&#xff1a; c20出来有一段时间了。其中一大功能就是终于支持协程了&#xff08;c作为行业大哥大级别的语言&#xff0c;居然到C20才开始支持协程&#xff0c;我也是无力吐槽了&#xff0c;让多少人等了多少年&#xff0c;等了多少青春&#xff09;但千呼万唤他终于还是来…

MySQL数据库 主从复制与读写分离

读写分离是什么 读写分离&#xff0c;基本的原理是让主数据库处理事务性增、改、删操作&#xff08;INSERT、UPDATE、DELETE&#xff09;&#xff0c;而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。 为什么要进行读写分离 因…

基于Matlab实现多个图像融合案例(附上源码+数据集)

图像融合是将多幅图像合成为一幅图像的过程&#xff0c;旨在融合不同图像的信息以获得更多的细节和更丰富的视觉效果。在本文中&#xff0c;我们将介绍如何使用Matlab实现图像融合。 文章目录 简单案例源码数据集下载 简单案例 首先&#xff0c;我们需要了解图像融合的两种主…

【STM32】IIC的初步使用

IIC简介 物理层 连接多个devices 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中&#xff0c;可连接多个 I2C 通讯设备&#xff0c;支持多个通讯主机及多个通讯从机。 两根线 一个 I2C 总线只使用两条总线线路&#xff0c;一条双向串行数…