C++修炼之筑基期第一层——认识类与对象


文章目录
- 🌷专栏导读
- 🌷什么是面向对象?
- 🌷类的引入
- 🌷什么是类
- 🌷类的定义方式
- 🌷类的访问限定符与封装
- 🌺访问限定符
- 🌺封装
- 🌷类的作用域
- 🌷类的实例化
- 🌷类对象模型
- 🌷this指针
- 🌺this指针的特性
- 🌷C语言与C++实现栈的对比
- 🌺C语言实现
- 🌺C++实现
🌷专栏导读
🌸作者简介:花想云,在读本科生一枚,致力于 C/C++、Linux 学习。
🌸本文收录于 C++系列,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新!
🌸相关专栏推荐:C语言初阶系列 、C语言进阶系列 、数据结构与算法
本章内容为C++修炼之筑基期系列的第一篇文章,初步认识类与对象,本章我们会学习什么是面向对象?类的定义、类的作用域、类的实例化、类对象模型以及this指针。此外筑基期系列文章都是关于类与对象的讲解。
🌷什么是面向对象?
学习C语言时,我们就经常听说C语言是面向过程的,那么什么是面向过程呢?举个例子,我们现在要完成洗衣服的工作,此刻我们关注的是洗衣服的过程:
- 拿个盆子;
- 接水;
- 放衣服;
- 到洗衣粉
- …

C语言是
面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。C++是
面向对象的,关注的是对象,在解决问题时,通过对象间的交互来完成,每个对象负责不同的工作。
例如,我们将洗衣服的任务分配给几个对象来完成:

🌷类的引入
C语言中,结构体内只能定义变量,在C++中,结构体内不仅可以定义变量,还可以定义函数。
以前用C语言实现数据结构——栈时,我们这样定义:
//C语言
typedef int dataOfStackType;typedef struct stack
{dataOfStackType* a;int top;int capacity;
}stack;void StackInit(stack* ps);void StackPush(stack* ps, dataOfStackType data);void StackPop(stack* ps);//...
而在C++中,我们可以这样定义:
//C++
typedef int dataOfStackType;typedef struct stack
{void StackInit(stack* ps);void StackPush(stack* ps, dataOfStackType data);void StackPop(stack* ps);
//...dataOfStackType* a;int top;int capacity;
}stack;
像上面的定义方式,C++中更喜欢用一个新的名字——class来代替struct。
class stack
{void StackInit(stack* ps);void StackPush(stack* ps, dataOfStackType data);void StackPop(stack* ps);
//...dataOfStackType* a;int top;int capacity;
};
🌷什么是类
class className
{//...类的主体:由成员函数和成员变量组成
};
如上所示,类的定义与结构体的定义非常相似,但我们还是得认识几个专有名词。
class:定义类的关键字;class Name:类的名字;类的主体:{}中为类的主体,由成员变量和成员方法组成;成员变量:又称类的属性,指在类中定义的变量;成员函数:又称类的方法,指在类中定义的函数;
🌷类的定义方式
类的定义方式一般有两种:
声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
//日期类
class Date
{void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}int _year;int _month;int _day;
};
类的声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::。
//Date.h文件中声明类
//日期类
class Date
{
public:void Init(int year, int month, int day);void Print();int _year;int _month;int _day;
};
//Date.c文件中定义成员函数
#include"Date.h"void Date::Init(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
void Date::Print()
{cout << _year << "-" << _month << "-" << _day << endl;
}
一般情况下,更期望采用第二种方式。至于其中的public是什么意思,这个等下再说。
🌷类的访问限定符与封装
🌺访问限定符
我们在类中定义了各种成员函数与成员变量,有时候,我们不想让别人随便访问类中的某些成员,比如成员变量,但其它的成员对外开放,比如成员函数,那么我们就需要用到访问限定符来修饰这些成员。
访问限定符有三个:public、protected、private。

访问限定符说明
class的默认访问权限为private,struct为public(因为struct要兼容C);public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问(此处 protected 和 private 是类似的);- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止;
- 如果后面没有访问限定符,作用域就到 } 即类结束。
注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。
一道面试题
问题:C++中 struct 和 class 的区别是什么?
解答: C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类默认访问权限是private。
🌺封装
面向对象有三大特性:封装、继承、多态。在当前阶段,我们只学习封装的特性。
- 什么是封装呢?
用专业一点的话来回答就是:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
封装本质上是一种管理,让用户更方便使用类。比如:对于电脑这样一个复杂的设备,提供给用户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。
在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。
🌷类的作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::作用域操作符指明成员属于哪个类域。
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " "<< _gender << " " << _age << endl;
}
🌷类的实例化
用类创建对象的过程,称为类的实例化。
//类的声明
class Date
{
public:void Init(int year, int month, int day);void Print();int _year;int _month;int _day;
};
有这样一个问题
- 上面实现的Date类占用多大的内存空间?
答案是,不占用空间。因为定义类只是一个描述对象的过程。
类实例化出对象就像现实中使用设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,而实例化出的对象才是真正盖好的房子,能实际存储数据,占用物理空间。
像设计图一样,并不是一幅设计图只能盖一个房子,一个类也可以实例化出多个对象。
class Date
{
public://...int _year;int _month;int _day;
};
int main()
{Date d1;Date d2;Date d3;cout << sizeof(d1) << endl;cout << sizeof(d2) << endl;cout << sizeof(d3) << endl;return 0;
}

🌷类对象模型
我们刚刚用sizeof观察了实例化出来的对象确实占用了内存空间,但是我们并不知道结果为什么是 12 。
上文已经提到,C++中,类与结构体本质是相同的。为了兼容C语言,C++肯定不能改变结构体大小的计算规则,而类与结构体相同(除默认访问限定符不同),那么类当然也是运用与结构体相同的计算规则。
- 类中定义的成员函数不会占用空间吗?
答案是并不占用,因为成员函数在公共代码段。
简单写个程序验证一下:
// 类中既有成员变量,又有成员函数
class A1 {
public:void f1() {}
private:int _a;
};// 类中仅有成员函数
class A2 {
public:void f2() {}
};// 类中什么都没有---空类
class A3
{};int main()
{cout << sizeof(A1) << endl;cout << sizeof(A2) << endl;cout << sizeof(A3) << endl;return 0;
}

结果显而易见,仅有成员函数的类与空的类大小是相同的,那么就验证了上面的说法。但是又出来一个新的问题:
- 为什么空类的大小为 1 呢?
答案是,空类比较特殊,编译器会给空类一个字节来唯一标识这个类的对象。
总结
一个类的大小,实际上是该类中成员变量的大小之和,当然与结构体相同,需注意内存对齐。空类须特殊处理,大小为1字节。
在C语言阶段,博主已经对结构体的内存对齐做了超级详细的讲解,若有遗忘的小伙伴点击此处跳转。
以下是对内存对齐的简单回忆。
结构体内存对齐规则
- 第一个成员在与结构体
偏移量为0的地址处。 - 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。注意:
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8 - 结构体总大小为:
最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。 - 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
🌷this指针
在类的成员函数中,有这样一个存在,我们无时无刻不在用它,但是我们却看不见它,这个神奇的存在就是this指针。
我们如何证明它存在呢?首先定义一个日期类。
//日期类
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
对它进行使用。
int main()
{Date d1, d2;d1.Init(2022, 1, 11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}
对于上述操作,有这样一个疑问:
- Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?
这就不得不提我们刚才谈到的this指针了。C++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
🌺this指针的特性

this指针有以下特性:
- this指针的类型:
类的类型* const,即成员函数中,不能给this指针赋值;
void Init(int year, int month, int day){//错误示例this=nullptr;}
- 只能在
成员函数的内部使用; - this指针本质上是
成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针; - this指针是
成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递;
有了this指针,我们上面实现的日期类还可以这样实现。
//日期类
class Date
{
public:void Init(int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}void Print(){cout <<this-> _year << "-" <<this-> _month << "-" <<this-> _day << endl;}
private:int _year;int _month;int _day;
};
但是在实际写代码的过程中没有必要这样写,既然编译器已经帮我们做了,我们就不要干吃力不讨好的事情。
到目前为止,我们已经简单的认识了类和对象,更多关于类和对象的内容还没有讲到。认识了类与对象,我们就简单对比一下C语言实现栈和C++中运用类实现栈的过程。
🌷C语言与C++实现栈的对比
🌺C语言实现
typedef int DataType;
typedef struct Stack
{DataType* array;int capacity;int size;
}Stack;
void StackInit(Stack* ps)
{assert(ps);ps->array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == ps->array){assert(0);return;}ps->capacity = 3;ps->size = 0;
}
void StackDestroy(Stack* ps)
{assert(ps);if (ps->array){free(ps->array);ps->array = NULL;ps->capacity = 0;ps->size = 0;}
}
void CheckCapacity(Stack* ps)
{if (ps->size == ps->capacity){int newcapacity = ps->capacity * 2;DataType* temp = (DataType*)realloc(ps->array,newcapacity * sizeof(DataType));if (temp == NULL){perror("realloc申请空间失败!!!");return;}ps->array = temp;ps->capacity = newcapacity;}
}
void StackPush(Stack* ps, DataType data)
{assert(ps);CheckCapacity(ps);ps->array[ps->size] = data;ps->size++;
}
int StackEmpty(Stack* ps)
{assert(ps);return 0 == ps->size;
}
void StackPop(Stack* ps)
{if (StackEmpty(ps))return;ps->size--;
}
DataType StackTop(Stack* ps)
{assert(!StackEmpty(ps));return ps->array[ps->size - 1];
}
int StackSize(Stack* ps)
{assert(ps);return ps->size;
}
int main()
{Stack s;StackInit(&s);StackPush(&s, 1);StackPush(&s, 2);StackPush(&s, 3);StackPush(&s, 4);printf("%d\n", StackTop(&s));printf("%d\n", StackSize(&s));StackPop(&s);StackPop(&s);printf("%d\n", StackTop(&s));printf("%d\n", StackSize(&s));StackDestroy(&s);return 0;
}
可以看到,在用C语言实现时,Stack相关操作函数有以下共性:
- 每个函数的第一个参数都是
Stack* - 函数中必须要对第一个参数
检测,因为该参数可能会为NULL - 函数中都是通过
Stack*参数操作栈的 - 调用时必须传递Stack结构体变量的地址
结构体中只能定义存放数据的结构,操作数据的方法不能放在结构体中,即数据和操作数据的方式是分离开的,而且实现上相当复杂一点,涉及到大量指针操作,稍不注意可能就会出错。
🌺C++实现
typedef int DataType;
class Stack
{
public:void Init(){_array = (DataType*)malloc(sizeof(DataType) * 3);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = 3;_size = 0;}void Push(DataType data){CheckCapacity();_array[_size] = data;_size++;}void Pop(){if (Empty())return;_size--;}DataType Top() { return _array[_size - 1]; }int Empty() { return 0 == _size; }int Size() { return _size; }void Destroy(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}
private:void CheckCapacity(){if (_size == _capacity){int newcapacity = _capacity * 2;DataType* temp = (DataType*)realloc(_array, newcapacity *sizeof(DataType));if (temp == NULL){perror("realloc申请空间失败!!!");return;}_array = temp;_capacity = newcapacity;}}
private:DataType* _array;int _capacity;int _size;
};
int main()
{Stack s;s.Init();s.Push(1);s.Push(2);s.Push(3);s.Push(4);printf("%d\n", s.Top());printf("%d\n", s.Size());s.Pop();s.Pop();printf("%d\n", s.Top());printf("%d\n", s.Size());s.Destroy();return 0;
}
C++中通过类可以将数据 以及 操作数据的方法进行完美结合,通过访问权限可以控制那些方法在类外可以被调用,即封装,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。而且每个方法不需要传递Stack*的参数了,编译器编译之后该参数会自动还原,即C++中 Stack *参数是编译器维护的,C语言中需用用户自己维护。

相关文章:
C++修炼之筑基期第一层——认识类与对象
文章目录🌷专栏导读🌷什么是面向对象?🌷类的引入🌷什么是类🌷类的定义方式🌷类的访问限定符与封装🌺访问限定符🌺封装🌷类的作用域🌷类的实例化&a…...
IT 运营监控工具
在技术复杂性日益增加、业务竞争激烈的挑战以及消费者对服务中断接受度降低的世界中,IT 运营效率已成为增长、利润和成功的关键。IT 宕机的影响在几十年前威胁较小,现在意味着价值数百万美元的损失,有时甚至会损失各种规模的组织的业务和声誉…...
java线程之Thread类的基本用法
Thread类的基本用法1. Thread类的构造方法2. Thread的几个常见属性常见属性线程中断等待一个线程小鱼在上一篇博客详细的讲解了如何创建线程,java使用Thread类来创建多线程,但是对于好多没有相关经验的人来说,比较不容易理解的地方在于操作系统调度的执行过程. 我们通过下面代码…...
【js】多分支语句练习(2)
个人名片: 😊作者简介:一名大一在校生,web前端开发专业 🤡 个人主页:python学不会123 🐼座右铭:懒惰受到的惩罚不仅仅是自己的失败,还有别人的成功。 🎅**学习…...
Redis与MySQL的双写一致性问题
Redis与MySQL的双写一致性问题更新缓存? 删除缓存?先更新缓存再更新数据库先更新数据库,再更新缓存先删除缓存再更新数据库先更新数据库,再删除缓存解决方案1. 重试2. 异步重试2.1 使用消息队列实现重试2.2 Binlog实现异步重试删除…...
Java基础:笔试题
文章目录Java 基础题目1. 如下代码输出什么?2. 当输入为2的时候返回值是多少?3. 如下代码输出值为多少?4. 给出一个排序好的数组:{1,2,2,3,4,5,6,7,8,9} 和一个数,求数组中连续元素的和等于所给数的子数组解析第一题第二题第三题第四题方案…...
spring三级缓存以及@Async产生循环引用
spring三级缓存以及Async产生循环引用spring三级缓存介绍三级缓存解除循环引用原理源码对应1、获取A,从三级缓存中获取,没有获取到2、构造A,将A置入三级缓存构造A(创建A实例)置入缓存3、注入属性,构造B扫描缓存实例的相关信息注入…...
【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(5)
目录 写在前面: 题目:P2036 [COCI2008-2009#2] PERKET - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述: 输入格式: 输出格式: 输入样例: 输出样例: 解题思路: 代码…...
【Unity3D】Unity3D中在创建完项目后自动创建文件夹列表
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 随着项目开发的体量增大,要导入大量的素材、UI、模…...
如何设计一个锂电池充电电路(TP4056)
这个是个单节18650锂电池的充电模块,这个是个18650的锂电池,18指的是它的直径是18mm,65指的是它的高度为65mm。这个18650电池的标称电压是3.7V,电池充满时电压为4.2V,一般电池电压越高也就代表它所剩的电量越大。这种锂…...
Spark了解
目录 1 概述 2 发展 3 Spark和Hadoop 4 Spark核心模块 1 概述 Apache Spark是一个快速、通用、可扩展的分布式计算系统,最初由加州大学伯克利分校的AMPLab开发。 Spark可以处理大规模数据处理任务,包括批处理、迭代式算法、交互式查询和流处理等。Spa…...
c++STL急急急
文章目录cSTL急急急vector头文件扩容过程用法:size/emptyclear迭代器begin/endfront/backpush_back() 和 pop_back()queue头文件用法循环队列 queue用法优先队列 priority_queue用法stack头文件deque头文件deque中控器:用法set头文件用法迭代器begin/end…...
【C++学习】模板进阶——非类型模板参数 | 模板的特化 | 分离编译
🐱作者:一只大喵咪1201 🐱专栏:《C学习》 🔥格言:你只管努力,剩下的交给时间! 模板我们之前一直都在使用,尤其是在模拟STL容器的时候,可以说,模板…...
【C++】C++11新特性——可变参数模板|function|bind
文章目录一、可变参数模板1.1 可变参数的函数模板1.2 递归函数方式展开参数包1.3 逗号表达式展开参数包1.4 empalce相关接口函数二、包装器function2.1 function用法2.2 例题:逆波兰表达式求值2.3 验证三、绑定函数bind3.1 调整参数顺序3.2 固定绑定参数一、可变参数…...
ssm框架之spring:浅聊事务--JdbcTemplate
简介 JdbcTemplate 是 Spring 对 JDBC 的封装,目的是使JDBC更加易于使用,JdbcTemplate是Spring的一部分。JdbcTemplate 处理了资源的建立和释放,它帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流&…...
盘点Python那些简单实用的第三方库
文章目录前言关于本文使用 pip 命令下载第三方库1、phone 库(获取手机号码信息)2、geoip2 库(IP 检测功能)3、freegames 库(免费小游戏)4、jionlp 库(解析地址信息)5、pyqrcode 库&a…...
leetCode热题21-26 解题代码,调试代码和思路
前言 本文属于特定的六道题目题解和调试代码。 1 ✔ [160]相交链表 Easy 2023-03-17 171 2 ✔ [54]螺旋矩阵 Medium 2023-03-17 169 3 ✔ [23]合并K个排序链表 Hard 2022-12-08 158 4 ✔ [92]反转链表 II Medium 2023-03-01 155 5 ✔ [415]字符串相加 Easy 2023-03-14 150 6 …...
ChatGPT推出第四代GPT-4!不仅能聊天,还可以图片创作!
3月15日凌晨,OpenAI震撼发布了多模态预训练大模型 GPT-4。 根据官网发布的通告可以知道,GPT-4 实现了以下几个方面的飞跃式提升:强大的AI创作识图能力;文字输入限制提升至 2.5 万字;回答准确性显著提高;能够…...
二叉搜索树:AVL平衡
文章目录一、 二叉搜索树1.1 概念1.2 操作1.3 代码实现二、二叉搜索树的应用K模型和KV模型三、二叉搜索树的性能分析四、AVL树4.1 AVL树的概念4.2 AVL树的实现原理4.3 旋转4.4 AVL树最终代码一、 二叉搜索树 1.1 概念 二叉搜索树( Binary Search Tree,…...
数据结构和算法(1):数组
目录概述动态数组二维数组局部性原理越界检查概述 定义 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识 In computer science, an array is a data structure consisting of a col…...
阿博图书馆管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
💡实话实说:用最专业的技术、最实惠的价格、最真诚的态度服务大家。无论最终合作与否,咱们都是朋友,能帮的地方我绝不含糊。买卖不成仁义在,这就是我的做人原则。摘要 在信息化时代背景下,图书馆作为知识传…...
多模态场景:头巾误判为厨师帽 — 问题分析与调优指南
多模态场景:头巾误判为厨师帽 — 问题分析与调优指南适用对象:使用 Qwen-VL 等多模态大模型做「厨师帽 / 头饰」相关识别时的面试问答、方案设计与落地调优参考。1. 问题本质:为什么会把头巾当成厨师帽 这通常不是「模型坏了」,而…...
OpenClaw数据清洗:Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF处理混乱CSV文件
OpenClaw数据清洗:Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF处理混乱CSV文件 1. 为什么需要自动化数据清洗 上周我接手了一个市场调研项目,客户发来的CSV文件打开就让我头皮发麻——编码混乱、字段名全是大写拼音缩写、日期格式五花八门。手动…...
不露脸也能当主播?一文了解VTuber
不露脸也能当主播?一文了解VTuber很多人提到 VTuber,脑子里就是“二次元纸片人”在直播间卖萌。 但其实,你每天换的微信头像、用过的苹果拟我表情,短视频平台的3D头套全都是它的“远房亲戚”。 今天我们就把这层科技外衣扒开&…...
2026降AIGC率工具实测:10款好用工具推荐(论文AI痕迹重必看)
临近毕业季,不少同学都在为论文的AIGC检测头疼:明明是自己写的内容,却被判定为AI生成?用AI搭了初稿,怎么改都消不掉机器痕迹?到底有没有靠谱的降AI率工具能真正解决问题? 今天我就给大家整理了1…...
SSD用久了为啥会变慢?深入NAND Flash的‘写放大’与‘磨损均衡’,教你看懂SMART数据避坑
SSD性能下降的真相:从写放大到磨损均衡的深度解析 你是否遇到过这样的困扰——新买的SSD速度飞快,但用了一段时间后,系统响应明显变慢,开机时间延长,文件传输速度大不如前?这种现象并非偶然,而是…...
2025最权威的十大AI学术神器推荐榜单
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 于人工智能生成内容也就是AIGC愈发普及的当前情形下,把它的机械痕迹以及同质化特…...
2026届必备的五大AI辅助论文助手实际效果
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 基于大语言模型与自然语言处理技术的 AI 写作软件,是内容生产领域新兴工具&…...
牙科手术显微镜市场:其中中国市场占比超15%
在口腔诊疗向精细化、微创化演进的进程中,牙科手术显微镜作为核心光学放大设备,凭借其高照度、高景深与高清晰度特性,成为提升根管治疗、牙周手术及种植修复等环节精准性的关键工具。该设备集成连续变倍观察、同轴照明、术野调焦及影像记录系…...
解决Python ssl模块与系统OpenSSL版本不一致的编译指南
1. 为什么Python的ssl模块会与系统OpenSSL版本不一致? 很多开发者都遇到过这样的困惑:明明系统已经升级了OpenSSL,为什么Python的ssl模块还在使用旧版本?这个问题其实源于Python的编译机制。Python在编译安装时,会将当…...
