【Cpp筑基】三、对象和类
【Cpp筑基】三、对象和类
【Cpp筑基】一、内联函数、引用变量、函数重载、函数模板
【Cpp筑基】二、声明 vs 定义、头文件、存储持续性作用域和链接性、名称空间
【Cpp筑基】三、对象和类
【Cpp筑基】四、重载运算符、友元、类的转换函数
【Cpp筑基】五、类的继承、虚函数、抽象基类
文章目录
- 【Cpp筑基】三、对象和类
- 1. 类
- 1.1 类的一个简单示例
- 1.2 类的访问权限
- 1.3 内联方法
- 1.4 构造函数和析构函数
- 1.5 C++11列表初始化
- 1.6 const成员函数
- 1.7 this指针
- Reference
1. 类
Cpp相比于C语言新增了类的概念,因此Cpp是一种面向对象的编程语言而C语言只是一种面向过程的编程语言。类是一种将抽象转换为用于自定义的Cpp工具,它将数据表示和操纵数据的方法组合成一个整洁的包。
一般来说,类规范由两部分组成:
- 类声明:以数据成员的方式描述数据部分,以成员函数(被称为方法)的方式描述公有接口。
- 类的方法定义:描述如何实现类成员函数。
1.1 类的一个简单示例
简单来说,类声明提供了类的蓝图,而方法定义则提供了类实现的细节。举一个例子:
my_class.h文件中存放了类的声明
// my_class.h
#ifndef MY_CLASS_H
#define MY_CLASS_H#include <iostream>
#include <string>// 类声明
class Person {
public:// 构造函数Person(const std::string &name, int age);// 公有接口:成员函数void display() const;void setAge(int age);int getAge() const;
private:// 数据成员std::string name;int age;
};#endif
my_class.cpp中存放了类的方法定义
// my_class.cpp
#include "my_class.h"
// 构造函数实现
Person::Person(const std::string &name, int age) : name(name), age(age) {}// display 方法实现
void Person::display() const {std::cout << "Name: " << name << ", Age: " << age << std::endl;
}// setAge 方法实现
void Person::setAge(int age) {if (age > 0) {this->age = age;} else {std::cout << "Invalid age!" << std::endl;}
}// getAge 方法实现
int Person::getAge() const {return age;
}
1.2 类的访问权限
Cpp中类的访问权限有三种:
public,公有,类的成员可以从类的外部直接访问。任何对象或函数都可以访问public成员protected,保护,类的成员不能从类的外部直接访问,但可以被派生类(继承该类的类)访问。private,私有,访问权限表示成员不能从类的外部直接访问,也不能被派生类访问。只有类的成员函数和友元函数可以访问private成员。
需要注意的是,在Cpp中访问权限是相对类的外部而言的,在类的内部来说,所有的变量和成员函数都是可以互相访问的。公有public方法也可以访问私有private成员变量和方法,Cpp类的成员函数,无论其访问级别如何,都可以访问该类中的所有成员,包括私有成员,这是因为成员函数被认为是类的一部分,拥有该类的所有细节的权限。
在Cpp中可以使用关键字struct或者class来声明一个类,它们的使用方式基本相同,唯一不同之处在于struct声明的成员默认访问权限为public,而class声明的成员默认访问权限是private。
数据隐藏作为面向对象编程(Object Orient Program,OOP)的主要目的,因此数据项通常放在私有部分,组成类接口的成员函数放在公有部分;否则就无法从程序中调用这些函数。通常,我们使用私有成员函数来处理不属于公有接口的实现细节。
1.3 内联方法
如果在一个类中,其成员函数的定义放在类的声明中,那么该成员函数将被自动转化为内联函数,以减小开销。内联函数是一种建议编译器在每次调用该函数时,将其代码插入到调用点处,而不是进行常规的函数调用。这可以减少函数调用的开销,提高程序执行效率,尤其是对于短小的函数。举个例子:
#include <iostream>class MyClass {
public:// 在类声明中定义的函数,自动转化成内联函数void printMessage() const {std::cout << "Hello, Inline Function!" << std::endl;}
};int main() {MyClass obj;obj.printMessage(); // 调用内联函数return 0;
}
当然我们也可以手动在类声明之外定义内联成员函数。举个例子:
#include <iostream>class MyClass {
public:void printMessage() const; // 声明时不需要 inline
};// 定义时使用 inline
inline void MyClass::printMessage() const {std::cout << "Hello, Inline Function!" << std::endl;
}int main() {MyClass obj;obj.printMessage();return 0;
}
使用new初始化类,使用new在heap区上分配内存来初始化一个类的指针会调用相应的构造函数,举个例子:
#include <iostream>class Complex {
private:double real, imag;public:// 默认构造函数Complex() : real(0), imag(0) {std::cout << "Default constructor called" << std::endl;}// 带参数的构造函数Complex(double r, double i) : real(r), imag(i) {std::cout << "Parameterized constructor called" << std::endl;}// 析构函数~Complex() {std::cout << "Destructor called" << std::endl;}// 显示函数void display() const {std::cout << "(" << real << ", " << imag << ")" << std::endl;}
};int main() {// 使用 new 动态分配对象Complex* c1 = new Complex(); // 调用默认构造函数Complex* c2 = new Complex(3.0, 4.0); // 调用带参数的构造函数// 使用对象c1->display();c2->display();// 释放动态分配的内存delete c1; // 调用析构函数并释放内存delete c2; // 调用析构函数并释放内存return 0;
}
1.4 构造函数和析构函数
在C++中,构造函数和析构函数是特殊的成员函数,用于在对象的生命周期内执行初始化和清理操作。构造函数在对象创建时自动调用,而析构函数在对象销毁时自动调用。
构造函数是用于初始化对象的特殊成员函数。构造函数的名称与类名相同,并且没有返回类型。构造函数可以被重载,即一个类可以有多个构造函数,只要它们的参数(特征标)不同。
构造函数的特点是:
- 名称与类名相同
- 没有返回类型
- 在对象创建时自动调用
- 可以被重载
- 可以使用初始化列表
- 不能成为虚函数
举个例子:
#include <iostream>class MyClass {
public:int x;
private:// 默认构造函数MyClass() {x = 0;std::cout << "Default Constructor called" << std::endl;}// 参数化构造函数MyClass(int value) {x = value;std::cout << "Parameterized Constructor called" << std::endl;}// 拷贝构造函数MyClass(const MyClass& obj) {x = obj.x;std::cout << "Copy Constructor called" << std::endl;}
};int main() {MyClass obj1; // 调用默认构造函数MyClass obj2(10); // 调用参数化构造函数MyClass obj3 = obj2; // 调用拷贝构造函数return 0;
}
这里重载了构造函数,提供了三种构造函数,当类被示例化的时候会从构造函数中选择符合特征标的构造函数进行调用。
成员名称与参数名,不熟悉构造函数的程序员可能会将类成员名称用作构造函数的参数名,例如:
class MyClass {
public:int x; // 成员变量MyClass(int x) { // 构造函数参数名与成员变量名相同x = x; // 这是错误的}
};
为了解决这种问题,我们可以在数据成员名前面增加_或者一些其他的标识,例如:
class MyClass {
public:int _x; // 成员变量MyClass(int x) { // 这是可行的,没有名称冲突_x = x; }
};
或者使用this指针来显示地指明
class MyClass {
public:int x; // 成员变量MyClass(int x) { // 这是可行的,使用this指针this->x = x; }
};
或者使用构造函数初始化列表,例如:
class MyClass {
public:int x; // 成员变量MyClass(int x) : x(x) { // 使用初始化列表// 这样更直观,并且避免了赋值操作}
};
如果Classy是一个类,且mem1和mem2是其成员变量,那么成员初始化列表的语法是:
Classy::Classy(int n, int m): mem1(n), mem2(m){ }
从概念上来说,这些初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码,请注意以下几点:
- 这种初始化格式只能适用于构造函数;
- 必须使用这种格式来初始化非静态
const数据成员; - 必须使用这种格式来初始化引用数据成员。
原因在于const变量和&引用都只能在被创建的时候进行初始化,举个例子:
- 初始化非静态
const数据成员
class MyClass{
private:const int qsize;
public:MyClass(int qs): qsize(qs) {}
}
- 初始化引用数据成员
class Agency {...};
class Agent{
private:Agency & belong; // must be initializer list to initialize
public:Agent(Agency& a): belong(a) {...}
}
如果没有提供构造函数,那么编译器会为我们添加一个默认构造函数,只不过这个构造函数什么也不执行;一个默认拷贝构造函数,并且重载赋值运算符=,允许我们直接拷贝已有的对象实例。
默认的构造函数,举个例子:
#include <iostream>class MyClass {
public:int x;double y;
};int main() {MyClass obj; // 使用编译器生成的默认构造函数std::cout << "x: " << obj.x << ", y: " << obj.y << std::endl; // 未定义行为return 0;
}
在这个类MyClass中,我们并没有定义构造函数,编译器自动帮我们生成了一个构造函数,这个构造函数什么都不做,所以x和y是没有赋值的,在最后一行的打印语句中将会报错。
默认拷贝构造函数,举个例子:
#include <iostream>class MyClass {
public:int x;double y;
};int main() {MyClass obj1;obj1.x = 10;obj1.y = 20.5;MyClass obj2 = obj1; // 使用编译器生成的默认拷贝构造函数std::cout << "obj2.x: " << obj2.x << ", obj2.y: " << obj2.y << std::endl;return 0;
}
在这个类MyClass中,我们并没有定义构造函数,编译器自动帮我们生成了一个拷贝构造函数,编译器生成的默认拷贝构造函数会逐个成员地进行浅拷贝。
重载运算符operator=,举个例子:
#include <iostream>class MyClass {
public:int x;double y;
};int main() {MyClass obj1;obj1.x = 10;obj1.y = 20.5;MyClass obj2;obj2 = obj1; // 使用编译器生成的默认赋值运算符std::cout << "obj2.x: " << obj2.x << ", obj2.y: " << obj2.y << std::endl;return 0;
}
编译器生成的默认赋值运算符(operator=)也会逐个成员地进行浅拷贝。
在Cpp中,析构函数是一个特殊的成员函数,用于在对象生命周期结束时执行清理工作,析构函数通常用于释放资源(如动态内存、文件句柄、网络连接等),确保对象在销毁时不会造成资源泄露。
析构函数的特点是:
- 名称与类名相同,但前面加上波浪号
~ - 没有返回类型
- 没有参数
- 在对象生命周期结束时自动调用
- 不能被重载,一个类只能有一个析构函数
- 不能成为虚函数
例如:
#include <iostream>class MyClass {
public:int* ptr;MyClass(int size) {ptr = new int[size];std::cout << "Constructor called" << std::endl;}~MyClass() {delete[] ptr;std::cout << "Destructor called" << std::endl;}
};int main() {MyClass obj(10); // 创建对象并分配内存// 离开作用域时自动调用析构函数,释放内存return 0;
}
如果你没有定义析构函数,那么编译器将会自动生成一个析构函数,该析构函数不执行任何操作,例如:
#include <iostream>class Simple {
public:int x;Simple() : x(0) {std::cout << "Simple Constructor" << std::endl;}// 编译器会生成一个默认析构函数// ~Simple() { }
};int main() {Simple obj; // 创建对象时调用构造函数return 0; // 离开作用域时调用编译器生成的默认析构函数
}
1.5 C++11列表初始化
在C++11中,列表初始化语法也可以用于类中,只要提供与某个构造函数的参数列表匹配的内容,就可使用大括号{}进行列表初始化。
列表初始化类的对象,举个例子:
#include <iostream>class MyClass {
public:int x;double y;// 默认构造函数MyClass(){}// 构造函数MyClass(int a, double b) : x(a), y(b) {std::cout << "MyClass constructed with x: " << x << ", y: " << y << std::endl;}
};int main() {MyClass jock {}; //使用默认构造函数进行初始化MyClass alex {10, 2.5}; //使用构造函数进行初始化MyClass john {2, 5.1}; //使用构造函数进行初始化return 0;
}
列表初始化类的对象的数组,举个例子:
#include <iostream>class MyClass {
public:int x;double y;// 默认构造函数MyClass(){}// 构造函数MyClass(int a, double b) : x(a), y(b) {std::cout << "MyClass constructed with x: " << x << ", y: " << y << std::endl;}
};int main() {// 使用列表初始化来初始化类对象数组MyClass arr[3] = { {1, 2.5}, {3, 4.5}, {5, 6.5}, };// 也可这样来初始化数组MyClass arry[3] = {MyClass(2, 2.5),MyClass(3, 1.5),MyClass(4, 6.5),};return 0;
}
1.6 const成员函数
在C++中,const成员函数是指那些不会修改类的成员变量的成员函数。通过在函数声明的末尾加上 const关键字,可以保证该函数不会修改对象的状态。这对于确保某些函数的调用不会意外地改变对象的状态非常有用,并且在设计接口和维护代码的稳定性方面起着重要作用。
const成员函数的基本使用,举个例子:
class MyClass {
public:int getValue() const; // 声明为const成员函数
private:int value;
};int MyClass::getValue() const {return value; // 可以读取成员变量// value = 10; // 错误:不能修改成员变量
}
const对象和成员函数,const对象不能调用非const成员函数,而非const对象可以调用所有的成员函数,举个例子:
class MyClass {
public:int getValue() const;void setValue(int v);
private:int value;
};int MyClass::getValue() const {return value;
}void MyClass::setValue(int v) {value = v;
}int main() {MyClass obj;obj.setValue(10);std::cout << obj.getValue() << std::endl; // 可以调用非const对象的所有成员函数const MyClass constObj;// constObj.setValue(10); // 错误:不能调用非const成员函数std::cout << constObj.getValue() << std::endl; // 只能调用const成员函数return 0;
}
1.7 this指针
在C++中,this指针是一个隐含在每个非静态成员函数中的特殊指针。它指向调用成员函数的对象,并且允许成员函数访问调用对象的成员变量和其他成员函数。this指针的主要作用是区分成员变量和局部变量,并在成员函数内部引用对象本身。
this指针的特点
- 指向调用对象:
this指针指向调用成员函数的对象本身。 - 只在非静态成员函数中可用:静态成员函数没有
this指针,因为静态成员函数是类级别的,而不是对象级别的。 - 类型:
this指针的类型是指向类类型的常量指针,例如对于类MyClass,this指针的类型是MyClass* const。 - 常量性:
this指针是一个常量指针,不能更改它指向的对象,但可以用来修改对象的成员。
使用this指针区分成员变量和局部变量,举个例子:
#include <iostream>class MyClass {
private:int value;
public:MyClass(int value) {// 使用this指针区分成员变量和构造函数参数this->value = value;}void setValue(int value) {// 使用this指针区分成员变量和函数参数this->value = value;}void printValue() const {std::cout << "Value: " << this->value << std::endl;}
};int main() {MyClass obj(10);obj.printValue();obj.setValue(20);obj.printValue();return 0;
}
使用this指针实现链式调用(返回*this),举个例子:
#include <iostream>class MyClass {
private:int value;
public:MyClass(int value) : value(value) {}MyClass& setValue(int value) {this->value = value;return *this; // 返回对象本身的引用}MyClass& incrementValue() {++this->value;return *this; // 返回对象本身的引用}void printValue() const {std::cout << "Value: " << this->value << std::endl;}
};
int main() {MyClass obj(10);obj.setValue(20).incrementValue().printValue(); // 链式调用return 0;
}
在这个例子中,我们实现了对象方法的链式调用,但链式调用更多地用在运算符重载当中,举个例子:
#include <iostream>class MyClass {
private:int value;public:MyClass(int value) : value(value) {}MyClass& operator+=(int other) {this->value += other;return *this; // 返回*this}void printValue() const {std::cout << "Value: " << this->value << std::endl;}
};
int main() {MyClass obj(10);obj += 5;obj.printValue(); // 输出:Value: 15return 0;
}
Reference
《C++ Primer Plus》
相关文章:
【Cpp筑基】三、对象和类
【Cpp筑基】三、对象和类 Cpp系列笔记目录 【Cpp筑基】一、内联函数、引用变量、函数重载、函数模板 【Cpp筑基】二、声明 vs 定义、头文件、存储持续性作用域和链接性、名称空间 【Cpp筑基】三、对象和类 【Cpp筑基】四、重载运算符、友元、类的转换函数 【Cpp筑基】五、类的继…...
数据库原理面试-核心概念-问题理解
目录 1.数据库、数据库系统与数据库管理系统 2.理解数据独立性 3.数据模型 4.模式、外模式和内模式 5.关系和关系数据库 6.主键与外键 7.SQL语言 8.索引与视图 9.数据库安全 10.数据库完整性 11.数据依赖和函数依赖 12.范式?三范式?为什么要遵…...
【JavaScript】JavaScript里的“先斩后奏”之王 shift()方法
定义: JavaScript中 shift 方法用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组! 解释: 成语解释: 先斩后奏是一个汉语成语,其拼音为xiān zhǎn hu zu。这个成语最早出自于汉班固的《汉书申屠嘉传》,原指先把罪犯处决,再向皇帝奏闻。在现代…...
Python面试宝典第32题:课程表
题目 你这个学期必须选修numCourses门课程,记为0到numCourses - 1。在选修某些课程之前,需要一些先修课程。先修课程按数组prerequisites给出,其中prerequisites[i] [ai, bi],表示如果要学习课程ai,则必须先学习课程b…...
简单介绍BTC的Layer2项目RGB
这里写自定义目录标题 介绍(历史背景,项目成员)核心技术组成部分一次性密封条(single-use-seals)客户端验证(client-side validation) 总结 注:该内容不构成投资建议,有些…...
跨境电商卖家必看:搭建安全稳定测评自养号环境系统
对于卖家而言,测评作为一种低成本、高回报的推广策略,对于提升产品流量、转化率、优化关键词质量分及增强链接权重等方面均发挥着积极作用。以下是自养号优势及测评环境搭建技术要点 一、搭建安全稳定的测评环境系统 核心要点: 硬件参数去…...
如何对open62541.h/open62541.c的UA_Client进行状态(在线/掉线)监控
文章目录 背景解决方案注意事项 背景 目前在利用open62541.h/open62541.c编写了一个与PLC进行OPCUA通讯的上位机程序。 上位机这边会定时对PLC的某个opcua变量进行写操作。但是假如PLC离线或者说拔掉网线,上位机就会直接崩溃死机,并且报如下的错误&…...
高等数学 第九讲 一元函数积分学的应用
1. 一元函数积分学的应用 文章目录 1. 一元函数积分学的应用1. 几何应用1.1 用定积分表达和计算平面图形的面积1.2 用定积分表达和计算旋转体的体积1.2.1 微分法1.2.2 二重积分法1.2.3 古尔丁定理1.2.4 旋转体的体积公式总结 1.3 用定积分表达和计算函数的平均数1.4 其他几何应…...
django如何更新数据库字段并与数据库保持同步?
关键步骤: 第一步: 执行:python manage.py makemigrations 你的项目名称第二步:它会提示你选1还是2,这里因为添加字段,所以选1第三步:出现>>>这个,直接输入这个第四步&am…...
jenkins插件 SSH Publishers
Jenkins 是一个开源的自动化服务器,常用于持续集成和持续交付 (CI/CD)。以下是一些与 Jenkins 相关的 SSH 发布者及其功能: SSH 插件: 功能: 允许 Jenkins 通过 SSH 执行远程命令。用户可以配置 SSH 服务器,使用 SSH 密钥进行身份…...
Kafka Client客户端操作详解
文章目录 基础客户端版本消息生产者消息消费者踩坑 客户端属性分析消费者分组消费机制生产者拦截器消息序列化消息分区路由机制生产者消息缓存机制发送应答机制生产者消息幂等性生产者消息事务 客户端流程总结 基础客户端版本 导入依赖 <properties><project.build.…...
【HarmonyOS NEXT星河版开发学习】小型测试案例15-博客列表
个人主页→VON 收录专栏→鸿蒙开发小型案例总结 基础语法部分会发布于github 和 gitee上面(暂未发布) 前言 该案例主要是ForEach渲染的练习,ForEach可以基于数组的个数,渲染组件个数(简化代码) 在…...
go-zero中统一返回前端数据格式的几种方式
方式一、直接定义一个成功和失败的方法,在代码里面修改(对代码有侵入,每次都要修改代码) 1、封装一个统一返回的方法 package utilsimport ("github.com/zeromicro/go-zero/rest/httpx""net/http" )type Body struct {Code int json:"code…...
【向量数据库】Ubuntu编译安装FAISS
参考官方的安装指导:https://github.com/facebookresearch/faiss/blob/main/INSTALL.md,不需要安装的可以跳过 ~$ wget https://github.com/facebookresearch/faiss/archive/refs/tags/v1.8.0.tar.gz ~$ tar -zxvf v1.8.0.tar.gz ~$ cd faiss-1.8.0 ~$ …...
制造知识普及(九)--企业内部物料编码(IPN)与制造商物料编码(MPN)
在日常的物料管理业务逻辑中,一物一码是物料管理的基本的业务规则,不管物料从产品开发还是仓库管理,甚至成本核算,都要遵循这个原则,才能保证产品数据的准确性,才具备唯一追溯的可行性。大部分企业都是这种…...
【整数规划】+【0—1规划】解决优化类问题(Matlab代码)
目录 文章目录 前言 一、整数规划 分类: 二、典例讲解 1.背包问题 2.指派问题 总结 前言 如果觉得本篇文章还不错的话,给作者点个赞鼓励一下吧😁😁😁 在规划问题中,有些最优解可能是分数或小数&am…...
Linux下如何使用Curl进行网络请求
在Linux系统上,Curl是一个非常强大的网络请求工具,可以用于发送各种类型的HTTP请求,并获取响应结果。它支持常见的HTTP方法,如GET、POST、PUT、DELETE等,还支持HTTPS、FTP等不同协议。Curl提供了丰富的参数选项&#x…...
PostgreSQL 触发器
PostgreSQL 触发器 PostgreSQL触发器是一种强大的数据库对象,它可以在特定的数据库事件发生时自动执行预定义的操作。这些事件可以是插入、更新或删除表中的行。触发器通常用于强制复杂的业务规则、提供审计跟踪、数据同步以及实现复杂的约束。 触发器的基本概念 …...
LeetCode——3131.找出与数组相加的整数I
通过万岁!!! 题目:给你两个数组nums1和nums2,然后让你找一个数,使得nums1的数加上这个数以后得到的数组nums1’与nums2是相同的。注意这里只要元素相同就好了,不一定顺序相同。思路:…...
【SpringMVC】详细了解SpringMVC中WEB-INF 目录资源,视图解析器和静态资源放行的使用。
目录 1. 回顾SpringMVC请求转发和重定向 2. WEB-INF资源目录 3. 视图解析器 4. 静态资源放行 1. 回顾SpringMVC请求转发和重定向 概念:在一个项目中功能非常多,也就意味着有非常多的Servlet,不同的Servlet的职不 同 ,而用户发起…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
