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

【Cpp筑基】三、对象和类

【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初始化类,使用newheap区上分配内存来初始化一个类的指针会调用相应的构造函数,举个例子:

#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是一个类,且mem1mem2是其成员变量,那么成员初始化列表的语法是:

Classy::Classy(int n, int m): mem1(n), mem2(m){ }

从概念上来说,这些初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码,请注意以下几点:

  • 这种初始化格式只能适用于构造函数;
  • 必须使用这种格式来初始化非静态const数据成员;
  • 必须使用这种格式来初始化引用数据成员。

原因在于const变量和&引用都只能在被创建的时候进行初始化,举个例子:

  1. 初始化非静态const数据成员
class MyClass{
private:const int qsize;
public:MyClass(int qs): qsize(qs) {}
}
  1. 初始化引用数据成员
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中,我们并没有定义构造函数,编译器自动帮我们生成了一个构造函数,这个构造函数什么都不做,所以xy是没有赋值的,在最后一行的打印语句中将会报错。

默认拷贝构造函数,举个例子:

#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指针的类型是指向类类型的常量指针,例如对于类MyClassthis指针的类型是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.范式&#xff1f;三范式&#xff1f;为什么要遵…...

【JavaScript】JavaScript里的“先斩后奏”之王 shift()方法

定义: JavaScript中 shift 方法用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组! 解释: 成语解释: ‌先斩后奏是一个汉语成语,其拼音为xiān zhǎn hu zu。这个成语最早出自于汉‌班固的《‌汉书‌申屠嘉传》,原指先把罪犯处决,再向皇帝奏闻。在现代…...

Python面试宝典第32题:课程表

题目 你这个学期必须选修numCourses门课程&#xff0c;记为0到numCourses - 1。在选修某些课程之前&#xff0c;需要一些先修课程。先修课程按数组prerequisites给出&#xff0c;其中prerequisites[i] [ai, bi]&#xff0c;表示如果要学习课程ai&#xff0c;则必须先学习课程b…...

简单介绍BTC的Layer2项目RGB

这里写自定义目录标题 介绍&#xff08;历史背景&#xff0c;项目成员&#xff09;核心技术组成部分一次性密封条&#xff08;single-use-seals&#xff09;客户端验证&#xff08;client-side validation&#xff09; 总结 注&#xff1a;该内容不构成投资建议&#xff0c;有些…...

跨境电商卖家必看:搭建安全稳定测评自养号环境系统

对于卖家而言&#xff0c;测评作为一种低成本、高回报的推广策略&#xff0c;对于提升产品流量、转化率、优化关键词质量分及增强链接权重等方面均发挥着积极作用。以下是自养号优势及测评环境搭建技术要点 一、搭建安全稳定的测评环境系统 核心要点&#xff1a; 硬件参数去…...

如何对open62541.h/open62541.c的UA_Client进行状态(在线/掉线)监控

文章目录 背景解决方案注意事项 背景 目前在利用open62541.h/open62541.c编写了一个与PLC进行OPCUA通讯的上位机程序。 上位机这边会定时对PLC的某个opcua变量进行写操作。但是假如PLC离线或者说拔掉网线&#xff0c;上位机就会直接崩溃死机&#xff0c;并且报如下的错误&…...

高等数学 第九讲 一元函数积分学的应用

1. 一元函数积分学的应用 文章目录 1. 一元函数积分学的应用1. 几何应用1.1 用定积分表达和计算平面图形的面积1.2 用定积分表达和计算旋转体的体积1.2.1 微分法1.2.2 二重积分法1.2.3 古尔丁定理1.2.4 旋转体的体积公式总结 1.3 用定积分表达和计算函数的平均数1.4 其他几何应…...

django如何更新数据库字段并与数据库保持同步?

关键步骤&#xff1a; 第一步&#xff1a; 执行&#xff1a;python manage.py makemigrations 你的项目名称第二步&#xff1a;它会提示你选1还是2&#xff0c;这里因为添加字段&#xff0c;所以选1第三步&#xff1a;出现>>>这个&#xff0c;直接输入这个第四步&am…...

jenkins插件 SSH Publishers

Jenkins 是一个开源的自动化服务器&#xff0c;常用于持续集成和持续交付 (CI/CD)。以下是一些与 Jenkins 相关的 SSH 发布者及其功能&#xff1a; SSH 插件&#xff1a; 功能: 允许 Jenkins 通过 SSH 执行远程命令。用户可以配置 SSH 服务器&#xff0c;使用 SSH 密钥进行身份…...

Kafka Client客户端操作详解

文章目录 基础客户端版本消息生产者消息消费者踩坑 客户端属性分析消费者分组消费机制生产者拦截器消息序列化消息分区路由机制生产者消息缓存机制发送应答机制生产者消息幂等性生产者消息事务 客户端流程总结 基础客户端版本 导入依赖 <properties><project.build.…...

【HarmonyOS NEXT星河版开发学习】小型测试案例15-博客列表

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面&#xff08;暂未发布&#xff09; 前言 该案例主要是ForEach渲染的练习&#xff0c;ForEach可以基于数组的个数&#xff0c;渲染组件个数&#xff08;简化代码&#xff09; 在…...

go-zero中统一返回前端数据格式的几种方式

方式一、直接定义一个成功和失败的方法,在代码里面修改(对代码有侵入,每次都要修改代码) 1、封装一个统一返回的方法 package utilsimport ("github.com/zeromicro/go-zero/rest/httpx""net/http" )type Body struct {Code int json:"code…...

【向量数据库】Ubuntu编译安装FAISS

参考官方的安装指导&#xff1a;https://github.com/facebookresearch/faiss/blob/main/INSTALL.md&#xff0c;不需要安装的可以跳过 ~$ 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)

在日常的物料管理业务逻辑中&#xff0c;一物一码是物料管理的基本的业务规则&#xff0c;不管物料从产品开发还是仓库管理&#xff0c;甚至成本核算&#xff0c;都要遵循这个原则&#xff0c;才能保证产品数据的准确性&#xff0c;才具备唯一追溯的可行性。大部分企业都是这种…...

【整数规划】+【0—1规划】解决优化类问题(Matlab代码)

目录 文章目录 前言 一、整数规划 分类&#xff1a; 二、典例讲解 1.背包问题 2.指派问题 总结 前言 如果觉得本篇文章还不错的话&#xff0c;给作者点个赞鼓励一下吧&#x1f601;&#x1f601;&#x1f601; 在规划问题中&#xff0c;有些最优解可能是分数或小数&am…...

Linux下如何使用Curl进行网络请求

在Linux系统上&#xff0c;Curl是一个非常强大的网络请求工具&#xff0c;可以用于发送各种类型的HTTP请求&#xff0c;并获取响应结果。它支持常见的HTTP方法&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;还支持HTTPS、FTP等不同协议。Curl提供了丰富的参数选项&#x…...

PostgreSQL 触发器

PostgreSQL 触发器 PostgreSQL触发器是一种强大的数据库对象&#xff0c;它可以在特定的数据库事件发生时自动执行预定义的操作。这些事件可以是插入、更新或删除表中的行。触发器通常用于强制复杂的业务规则、提供审计跟踪、数据同步以及实现复杂的约束。 触发器的基本概念 …...

LeetCode——3131.找出与数组相加的整数I

通过万岁&#xff01;&#xff01;&#xff01; 题目&#xff1a;给你两个数组nums1和nums2&#xff0c;然后让你找一个数&#xff0c;使得nums1的数加上这个数以后得到的数组nums1’与nums2是相同的。注意这里只要元素相同就好了&#xff0c;不一定顺序相同。思路&#xff1a…...

【SpringMVC】详细了解SpringMVC中WEB-INF 目录资源,视图解析器和静态资源放行的使用。

目录 1. 回顾SpringMVC请求转发和重定向 2. WEB-INF资源目录 3. 视图解析器 4. 静态资源放行 1. 回顾SpringMVC请求转发和重定向 概念&#xff1a;在一个项目中功能非常多&#xff0c;也就意味着有非常多的Servlet&#xff0c;不同的Servlet的职不 同 &#xff0c;而用户发起…...

如何学好uni-app

学习uni-app需要掌握以下技能&#xff1a; 1. 前端基础&#xff1a;熟悉HTML、CSS和JavaScript等前端开发技术&#xff0c;了解基本的前端框架如Vue.js。 2. Vue.js&#xff1a;因为uni-app是基于Vue.js构建的&#xff0c;所以需要对Vue.js有深入的理解。可以先通过官方文档或者…...

C++ QT使用stackwidget实现页面切换(含源码)

C++ QT使用stackwidget实现页面切换(含源码) 0.前言1.UI布局1.1使用stackwidget2.代码方式添加页面实现页面切换3.源码4.最终效果0.前言 在QT中一个界面中如何实现页面的切换,而不是新弹出的窗口,这里采用的stackwidget,以层叠widget的方式选定页面索引从而实现页面切换。…...

打工人上班适合用的蓝牙耳机推荐?几款开放式耳机推荐

日常工作的话&#xff0c;我还是比较推荐开放式蓝牙耳机的&#xff0c;它特别适合那些需要在长时间工作中保持专注和舒适度的环境&#xff0c;那开放式耳机其实还有一些主要的优点&#xff1a; 减少耳朵疲劳&#xff1a;由于开放式耳机不需要紧密贴合耳朵&#xff0c;因此可以…...

一款.NET开发的AI无损放大工具

一款.NET开发的AI无损放大工具 思维导航 前言项目功能支持语言系统要求项目源代码项目运行小图片进行无损放大项目源码地址优秀项目和框架精选 前言 今天大姚给大家分享一款由.NET开源&#xff08;GPL-3.0 license&#xff09;、基于腾讯ARC Lab提供的Real-ESRGAN模型开发的A…...

编程新手必看:彻底理解!与~的取反操作

在编程和计算机科学的语境中&#xff0c;! 和 ~ 都是取反操作符&#xff0c;但它们的应用方式和效果存在显著的区别。下面将从定义、应用场景、作用原理及示例等方面对 ! 和 ~ 进行详细解析。 一、定义 !&#xff08;逻辑非运算符&#xff09; 在C语言、Java等多数编程语言中&…...

【LeetCode】54. 螺旋矩阵

螺旋矩阵 题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a;…...

计算机毕业设计 奖学金评定管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

【JavaWeb项目】——外卖订餐系统之商家添加餐品、修改餐品、查询热卖餐品、查询出售车、进行发货操作

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…...

制作抖音私信卡片 - 一键调起并跳转微信二维码

抖音私信图文卡片&#xff0c;点击可以直接一键添加微信 可生成无风险链接&#xff0c;使用苹果手机转发创建出卡片 抖音内点击可以直接调起微信跳入小程序展示微信二维码...

赋能未来园区:TSINGSEE视频AI智能管理平台如何引领园区管理智慧化转型

一、建设背景 随着经济的不断发展&#xff0c;园区产业集聚发展已成为趋势&#xff0c;园区逐渐成为产业聚集的重要载体。目前&#xff0c;国内现有的大部分园区的管理方式比较粗放、单一&#xff0c;范围局限于安全、环境等方面且不成体系&#xff0c;并且没有覆盖到应急、消…...