【C++篇】类与对象(中篇) 解密C++类的核心:六大默认成员函数详解与避坑指南
文章目录
- 前言
- 一、类的六个默认成员函数
- 二、构造函数
- 1. 概念
- 2. 特性(牢记)
- 三、析构函数
- 1. 概念
- 2. 特性(牢记)
- 四、拷贝构造函数
- 1. 概念
- 2. 特性(牢记)
- 五、赋值运算符重载
- 1. 运算符重载
- 2. 赋值运算符重载
- 前置++和后置++重载
- 六、const成员函数
- 七、取地址及const取地址操作符重载
前言
大家好呀,我是我想吃余😁!这次我们学习的内容非常非常重要🔑,如果本章内容懵懵懂懂的话,那么将导致你无法写出一个正确的类,更别说写一个C++程序了。因此,今天的内容务必理解透彻。
默认成员函数是C++的门槛,因为其内容较为抽象复杂,导致C++难学的名头流传至今😂。其实并没有这么夸张,根本不必畏惧,学完之后你会感觉:也就那回事!
翻过这座大山,我们将正式踏入C++的旅程🛫
本文共有9000余字(鬼知道我写了多久😪),干货满满。建议读者选择宽裕的时间学习哦🥰
一、类的六个默认成员函数
如果一个类中什么成员也没有,那么这个类称为空类
class Date
{};
难道空类中什么都没有吗?
答案是NO!
当类什么都不写时,编译器会自动生成6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
二、构造函数
在我们过去学习数据结构时,用C语言实现栈、队列、堆……都需要手动调用和定义初始化Init
和销毁Destroy
函数对数据进行初始化和清理。
如果每次创建对象时都调用该方法设置信息,未免有点麻烦了,那能否在对象创建时,就将信息设置进去呢?
有的兄弟有的!
1. 概念
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。
2. 特性(牢记)
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。
- 函数名与类名相同
- 无返回值(注意区分void,void也属于返回值)
- 对象实例化时编译器自动调用对应的构造函数
- 构造函数可以重载
class Date
{public:// 1.无参构造函数Date(){_year = 1;_month = 1;_day = 1;}// 2.带参构造函数Date(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day;
};void TestDate()
{Date d1; // 调用无参构造函数Date d2(2015, 1, 1); // 调用带参的构造函数Date d3();//错误写法,编译器会报错// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
}
- 💡:关于
Data d3()
,编译器将无法区分这是d3
是对象还是函数名,导致冲突。
- 如果类中没有显示定义构造函数,则C++编译器会自动生成一个无参的默认构造函数;一旦类中显示定义了,编译器将不再生成。
class Date
{public:/*// 如果用户显式定义了构造函数,编译器将不再生成Date(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类中构造函数屏蔽后,代码可以通过编译,因为编译器生成了一个无参的默认构造函数
// 将Date类中构造函数放开,代码编译失败,因为一旦显式定义任何构造函数,编译器将不再生成
// 无参构造函数,放开后报错:error C2512: “Date”: 没有合适的默认构造函数可用
Date d1;
return 0;
}
-
无参的构造函数和全缺省的构造函数以及编译器自己生成的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
- 💡:不要将无参构造函数和全缺省构造函数进行重载。它们虽然可以构成重载,但是在无参调用它们的时侯会产生歧义(编译器不知道要调用哪个,导致报错)
//错误示例 class Date {public:Date(){_year = 1900;_month = 1;_day = 1;}Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day; }; void Test() {Date d1; }
-
编译器生成的默认构造函数存在局限:
- 对于内置类型,不做初始化处理
- 对于自定义类型,会去调用它的默认构造函数
内置类型:语言本身定义的基础类型,int/char/double/指针……
自定义类型:用户自己定义的类型,class/struct……
如果我们不写构造函数,编译器默认生成构造函数,内置类型不做处理,自定义类型会去调用它的默认构造函数。
💡:有些编译器也会处理,但这是个性化行为,其实这是违反C++标准规定的,但不是所有编译器都会去处理的。因此为确保我们程序的可移植性,我们一律视为编译器不做处理,自行解决。
后来,C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在
类中声明时可以给默认值。
class Time
{public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}private:int _hour;int _minute;int _second;
};
class Date
{private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;
};int main(){Date d;return 0;
}
结论:
1. 一般情况下,构造函数都需要我们自己写
2. 不用写的特殊情况:
- 内置类型成员都用缺省值,且缺省值符合我们的初始化要求
- 所有成员都是自定义类型成员,且这些自定义类型都定义了默认构造函数。(可能有点晦涩,下面有详细的解释)
在我们实现栈的时候,是需要自己写构造函数的。但我们用栈实现队列时,这时候只需要用到两个栈(一个栈用来出队列,另一个用来入队列),符合“所有成员都是自定义类型成员”条件。但如果实现栈时没有写构造函数,那么这个队列自然会出错了,这里不符合“自定义类型都定义了默认构造函数”条件。
- 构造函数调用顺序原则:⼀个局部域的多个对象,先定义的先调用构造
三、析构函数
通过构造函数的学习,现在我们知道一个对象怎么初始化的,那一个对象是怎么进行资源清理的呢?
1. 概念
与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
2. 特性(牢记)
- 析构函数名是在类名前加上字符
~
- 无参数无返回值类型
- 应该类只有一个析构函数,不能重载。若未显示定义析构函数,编译器会自动生成默认析构函数。
- 对象生命周期结束时,C++编译系统自动调用析构函数。
使用实例(栈)
~Stack()
{if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}
}
- 跟构造函数类似,我们不写编译器⾃动⽣成的析构函数
- 内置类型成员不做处理
- ⾃定类型成员会调⽤他的析构函数。
class Time
{public:~Time(){cout << "~Time()" << endl;}private:int _hour;int _minute;int _second;
};
class Date
{private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;
};
int main()
{Date d;return 0;
}
程序运行结束后输出:~Time()
,说明调用了Time
类的析构函数。
我们根本没有直接去创建Time
类的对象呀,为什么还会调用它的析构函数呢?
我们来逐步分析代码:
我们创建了Date
类的对象d
,而d
中有4
个成员变量。
其中_year、 _month、_day
是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;
而_t
是Time
类对象 ,d
销毁时,要将其内部包含的Time
类的_t
对象销毁,所以会调用Time
类的析构函数。
注意:main函数中并没有直接调用Time类析构函数,而是显式调用编译器为Date类生成的默认析构函数,默认析构函数再调用Time类析构函数。
💡:创建那个对则调用该类的构造函数,销毁哪个类的对象则调用该类的析构函数
- 一般情况下,有动态申请资源,就需要自己写析构函数释放资源。
不需要写的两种情况:
- 没有动态申请的资源,不需要写析构函数
- 需要释放资源的成员都是自定义类型,不需要写析构函数
实现Stack
类时,需要动态申请内存,需要写;
class Stack
{private:STDataType* _a;size_t _capacity;size_t _top;
};
实现Date
类时,成员都是内置类型,没有动态申请资源,不需要写;
class Date
{private:int _year;int _month;int _day;
};
实现MyQueue
类(两个栈实现队列)时,需要释放资源的成员都是自定义类型,不需要写。
// 两个Stack实现队列
class MyQueue
{private:Stack pushst;Stack popst;
};
- 析构函数调用顺序原则:⼀个局部域的多个对象,规定后定义的先析构
与构造相反,可以反着来记。
本质上是看对象的生命周期,哪个对象的生命周期先结束哪个对象就先调用析构。
生命周期要看作用域,出作用域了,生命周期就结束了。
💡:全局变量和静态变量在程序结束后生命周期才结束,可以将它们看作在同一作用域中。
四、拷贝构造函数
在创建对象时,可否创建一个与已存在对象一某一样的新对象呢?
1. 概念
拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const
修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。
2. 特性(牢记)
- 拷贝构造函数是构造函数的一个重载形式
所以函数名也与类名相同且也无返回值
- 拷贝构造的参数只有一个且必须是类类型对象的引用。如果使用传值,编译其会报错(引发无穷递归)。
为什么会发生无穷递归呢?
我们来深入探索👁:
C++的拷贝规定:
- 内置类型直接拷贝
- 自定义类型必须调用拷贝构造函数完成拷贝。
我们都知道,函数的传值其实就是拷贝,而类是自定义类型,想要传值就要进行拷贝,想要拷贝就需要调用拷贝构造,拷贝构造又要传值,传值就要拷贝构造,拷贝构造就要传值,传值就要拷贝构造,拷贝构造就要传值,传值就要拷贝构造…… 发生无穷递归。
💡:拷贝构造函数的参数一定要用引用,千万不能用传值
class Date
{public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// Date(const Date& d) // 正确写法Date(const Date d) // 错误写法:编译报错,会引发无穷递归{_year = d._year;_month = d._month;_day = d._day;}private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(d1);return 0;
}
另外参数最好用是const
修饰,目的是为了防止出错,因为总是会有小可爱会写反🤐:
Date(const Date& d) {d._year = _year;d._month = _month;d._day = _day;}
用上const
编译器就会提醒你啦!!!
- 如果没有显示定义,编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储的字节序完成值拷贝,又称浅拷贝。
在编译器生成的默认拷贝构造函数中:
- 内置类型是按照字节方式直接拷贝的(浅拷贝/值拷贝)
- 自定义类型是调用其拷贝构造函数完成拷贝的(深拷贝)
深拷贝以后我会讲解,这里只需要知道:它会另外开辟一块空间,将其拷贝到这块空间。
- 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?
- 类中如果没有涉及资源申请时,拷贝构造函数是否写都可以
- 涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝
- 拷贝构造函数典型调用场景:
- 使用已存在对象创建新对象
- 函数参数类型为类类型对象
- 函数返回值类型为类类型对象
class Date
{public:Date(int year, int minute, int day){cout << "Date(int,int,int):" << this << endl;}Date(const Date& d){cout << "Date(const Date& d):" << this << endl;}~Date(){cout << "~Date():" << this << endl;}private:int _year;int _month;int _day;
};
Date Test(Date d)
{Date temp(d);return temp;
}
int main()
{Date d1(2022,1,13);Test(d1);return 0;
}
💡:为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用尽量使用引用。
五、赋值运算符重载
1. 运算符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
书写方式:
返回值类型 operator操作符(参数列表)
operator是关键字
💡:操作符是几个操作数,重载函数就有几个参数
- 必须用运算符的操作符,不能用其他的符号,如operator$
- 作为类成员函数重载时,其形参表面看起来比操作数数目少1,因为参数隐藏了一个this。
.*
、::
、sizeof
、?:
、.
,这5个运算符不能重载,这个在笔试选择题会考
2. 赋值运算符重载
- 格式
- 参数类型:const T&
传递引用可以提高传参效率和防止无穷递归 - 返回值类型:T&
返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值 - 检测是否自己给自己赋值
- 返回*this
还是以Date为例:
class Date
{
public :
Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
Date (const Date& d){_year = d._year;_month = d._month;_day = d._day;}
Date& operator=(const Date& d)
{if(this != &d)//检测是否自己给自己赋值{_year = d._year;_month = d._month;_day = d._day;}return *this;
}
private:int _year ;int _month ;int _day ;
};
- 赋值运算符只能重载成类的成员函数不能重载成全局函数
《C++ prime》第五版:
原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现
一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,所以赋值运算符重载只能是类的成员函数。
- 默认生成的赋值重载和拷贝构造的行为一样:
- 内置类型成员——值拷贝/浅拷贝
- 自定义类型成员会去调用它的赋值重载
与拷贝构造类似:
- 如果类中未涉及到资源管理,赋值运算符是否实现都可以
- 一旦涉及到资源管理则必须要实现。
前置++和后置++重载
- 前置++:返回+=1后的返回值,对象也+=1了
- 后置++:返回原对象的返回值,对象+=1
前置++和后置++都是一元运算符,所以两个函数都不需要参数,那么如何构成函数重载呢?
C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器自动传递
Date operator++(int)
💡:这个int没有任何含义,仅仅只是为了构成函数重载
代码实现:
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// 前置++:返回+1之后的结果// 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率Date& operator++(){_day += 1;return *this;}
// 后置++:
// 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this+1
//而temp是临时对象,因此只能以值的方式返回,不能返回引用Date operator++(int){Date temp(*this);_day += 1;return temp;}
private:int _year;int _month;int _day;
};
int main()
{Date d;Date d1(2022, 1, 13);d = d1++; // d: 2022,1,13 d1:2022,1,14d = ++d1; // d: 2022,1,15 d1:2022,1,15return 0;
}
六、const成员函数
先来看一段代码:
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << "Print()" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}
private:int _year; // 年int _month; // 月int _day; // 日
};
void Test()
{Date d1(2022,1,13);d1.Print();const Date d2(2022,1,13);d2.Print();
}
咦?怎么报错了呢?
d1.Print()
是肯定没问题的,因为我们之前一直都这样用,那问题一定在d2
调用Print
了。
问题锁定位置后,我们来看看d2.Print()
的传参情况:
- 实参为
&d2
; - 形参为
Date* this
.
然而,d2
的类型是const Date
,这不是妥妥的权限放大嘛!(const Date -> Date
)
这就导致了我们不能用const的对象调用成员函数,那么有什么方法可以解决这个问题呢?
有的兄弟有的
我们只需要改变this指针的参数类型就可以了:
Date* this -> const Date* this
但this指针是隐藏,该如何修改呢?
为此C++引出了const成员函数:
将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this
指针,表明在该成员函数中不能对类的任何成员进行修改。
在成员函数的后面加上const
💡:声明和定义都需要加const
这样一来,无论是cons对象
还是非const对象
都可以随意调用成员函数了。
那能不能所有成员函数都要加const
呢?
NO!
要修改对象成员变量的函数不能加const
!!!
否则编译器会报错。
💡:只要成员函数内部不修改成员变量,都应该加const,这样一来const对象和普通对象都可以调用这些成员函数
七、取地址及const取地址操作符重载
这两个默认成员函数一般无需自己定义,编译器会默认生成。
class Date
{
public :Date* operator&(){return this ;}const Date* operator&()const{return this ;}
private :int _year ; // 年int _month ; // 月int _day ; // 日
};
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容
💡:这两个默认成员函数了解即可,一般不用我们自己实现。
希望这篇文章对你有帮助♥
相关文章:
【C++篇】类与对象(中篇) 解密C++类的核心:六大默认成员函数详解与避坑指南
文章目录 前言一、类的六个默认成员函数二、构造函数1. 概念2. 特性(牢记) 三、析构函数1. 概念2. 特性(牢记) 四、拷贝构造函数1. 概念2. 特性(牢记) 五、赋值运算符重载1. 运算符重载2. 赋值运算符重载前…...
001 vue
https://cn.vuejs.org/ 文章目录 v-bindv-modelv-on修饰符条件渲染/控制:v-if v-show列表渲染 M:即Model,模型,包括数据和一些基本操作 V:即View,视图,页面渲染结果 VM:即View-Mode…...
web forms可视化开发显示的网页是用ExpressionWebEditorFrame控件,是IE内核还是简单的HTML解析?如何让他加载CSS和JS?
web forms可视化开发显示的网页是用ExpressionWebEditorFrame控件,是IE内核还是简单的HTML解析?如何让他加载CSS和JS? 1. ExpressionWebEditorFrame 控件的内核及解析机制 在 Visual Studio 中用于 Web Forms 可视化开发的 ExpressionWebEditorFrame 控件主要基于 Internet…...
$R^n$超平面约束下的向量列
原向量: x → \overset{\rightarrow}{x} x→ 与 x → \overset{\rightarrow}{x} x→法向相同的法向量(与 x → \overset{\rightarrow}{x} x→同向) ( x → ⋅ n → ∣ n → ∣ 2 ) n → (\frac{\overset{\rightarrow}x\cdot\overset{\righta…...
英伟达新一代GPU架构(50系列显卡)PyTorch兼容性解决方案
随着NVIDIA不断推出基于新架构的GPU产品,机器学习框架需要相应地更新以支持这些硬件。本文记录了在RTX 5070 Ti上运行PyTorch时遇到的CUDA兼容性问题,并详细分析了问题根源及其解决方案,以期为遇到类似情况的开发者提供参考。 在Anaconda虚…...
16.2Linux自带的LED灯驱动实验(详细编写)_csdn
这个实验不用自己编写代码。 1、在linux源代码中,打开 stm32mp15-pinctrl.dtsi 文件并进行修改: make uImage LOADADDR0XC2000040 -j8 //编译内核然后: 2、修改设备节点,打开 stm32mp157d-atk.dts: 其中࿱…...
Java 大视界 -- Java 大数据在智慧交通停车场智能管理与车位预测中的应用实践(174)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
HashMap 底层原理详解
1. 核心数据结构 JDK 1.7 及之前:数组 链表 JDK 1.8 及之后:数组 链表/红黑树(链表长度 ≥8 时转红黑树,≤6 时退化为链表) // JDK 1.8 的 Node 定义(链表节点) static class Node<K,V&g…...
重生之我是去噪高手——diffusion model
diffusion model是如何运作的? 想象一下,你有一张清晰的图片。扩散模型的核心思想分为两个过程: 前向过程(Forward Process / Diffusion Process):逐步加噪反向过程(Reverse Process / Denois…...
FfreeRTOS有阻塞作用的API
在 FreeRTOS 中,阻塞 API 是指那些会导致调用任务进入阻塞状态(Blocked State)的函数,即任务会暂时让出 CPU,直到某个条件满足(如超时、信号量可用、队列数据到达等)。以下是常见的阻塞 API 分类及示例: 1. 任务延迟(延时) vTaskDelay() 使任务阻塞指定的时间(以系统…...
app逆向专题二:app逆向流程
app逆向专题二:app逆向流程 一、app逆向说明二、拿到APP应用的apk三、使用工具进行查壳四、有壳需要先进行脱壳,拿到dex文件进行反编译五、使用Jadx-Gui或其他工具进行反编译,分析源码;六、根据app的抓包情况拿到加密的关键词参数…...
VMware 安装 Ubuntu 全流程实战指南:从零搭建到深度优化
在软件开发、系统测试以及技术学习等诸多场景中,使用虚拟机安装操作系统是一种灵活且高效的方式。Ubuntu 作为一款优秀的开源操作系统,在 VMware 虚拟机上的安装与优化备受关注。接下来,将为大家带来 VMware 安装 Ubuntu 的全流程实战指南&am…...
论文阅读笔记——RDT-1B: A DIFFUSION FOUNDATION MODEL FOR BIMANUAL MANIPULATION
RDT-1B 论文 模型表达与泛化能力:由于双臂操作中动作空间维度是单臂空间的两倍,传统方法难以建模其多模态分布。 数据:双臂数据少且不同机器人的物理结构和动作空间差异(如关节数、运动范围)导致数据分布不一致&#x…...
如何一天背300到500个单词
买一本有结构分析或词源注释的目标词汇书。 买一盒口香糖。 准备一摞空白的A4纸。 找一间用于冥想的黑屋子(眼晴闭上就可以了)。 将要背诵的单词进行分组: 5个一小组10个一中组50个一大组100个一个基本包或单元。给自己一个约定,比如背完一中组或一大组单词,嚼一粒口香糖…...
vs环境中编译osg以及osgQt
1、下载 OpenSceneGraph 获取源代码 您可以通过以下方式获取 OSG 源代码: 官网下载:https://github.com/openscenegraph/OpenSceneGraph/releases 使用 git 克隆: git clone https://github.com/openscenegraph/OpenSceneGraph.git 2、下载必要的第三方依赖库 依赖库 ht…...
C++ - 头文件基础(常用标准库头文件、自定义头文件、头文件引入方式、防止头文件重复包含机制)
一、头文件 在 C 中,头文件(.h)用于函数声明、类定义、宏定义等等 在 Visual Studio 中,头文件通常放在头文件目录中,头文件实现通常放在源文件目录中 二、常用标准库头文件 1、输入输出 <iostream> 标准输入…...
12款字重国外法国风格复古报纸日历设计衬线英文字体安装包 Claire Font Family
Claire 是一个带有坚固衬线的字体系列。该系列中的几种粗细字体非常适合设置大量连续文本;另一方面,极轻和极重的字体在显示应用中配合使用效果很好。Clair 中的字体具有垂直轴,其设计让人联想到当代报纸字体以及 Century 模型中的十九世纪晚…...
Java 类型转换和泛型原理(JVM 层面)
一、类型转换 概念解释: 编译类型:在编译时确定,保存在虚拟机栈的栈帧中的局部变量表中; 运行类型:在运行时确定,由保存在局部变量表中变量指向的堆中对象实例的类型决定(存储在对象头中&…...
ffmpeg基础知识入门
文章目录 📦 1. **容器(Container)**✅ 定义:✅ 举例:✅ 功能: 📶 2. **媒体流(Stream)**✅ 定义:✅ 举例:✅ 流和容器关系: …...
k8s 1.23升级1.24
0、简介 这里只用3台服务器来做一个简单的集群,当前版本是1.23.17目标升级到1.24.17 地址主机名192.168.160.40kuber-master-1192.168.160.41kuber-master-2192.168.160.42kuber-node-1 我这里设置的master2可调度pod,将master2的污点去掉 kubectl de…...
MIPI与DVP接口摄像头:深度解析与应用指南
1、MIPI 1.1 MIPI简介 MIPI是什么?MIPI:mobile industry processor interface移动行业处理器接口。它是一个由Intel、Motorola、Nokia、NXP、Samsung、ST(意法半导体)和TI(德州仪器)等公司发起的开放标准…...
liunx输入法
1安装fcitx5 sudo apt update sudo apt install fcitx fcitx-pinyin 2配置为默认输入法 设置-》系统-》区域和语言 点击系统弹出语言和支持选择键盘输入法系统 3设置设置 fcitx-configtool 如果没显示需要重启电脑 4配置fcitx 把搜狗输入法放到第一位(点击下面…...
马吕斯定律(Malus‘s Law)
马吕斯定律(Maluss Law)详解 马吕斯定律是偏振光学中的基本定律,由法国物理学家**tienne-Louis Malus**于1809年发现,描述了**线偏振光**通过检偏器后的光强变化规律。 2. 实验验证 3. 数学推导 4. 关键应用 5. 特殊情况讨论 …...
大厂算法面试 7 天冲刺:第6天-树与图深度剖析——高频算法面试题 Java 实战
🧠 第6天:树与图深度剖析——高频算法面试题 & Java 实战 📚 一、核心知识概览 Overview 1. 树(Tree) 树是一种非线性数据结构,常见于面试中的二叉树(Binary Tree)、二叉搜索树…...
C语言编译和链接错题
一、错题重现 1.用在switch语句中的关键字不包含哪个?( ) A.continue B.break C.default D.case 2.下面代码的结果是:( ) A.3 B.4 C.随机值 D.5 3.下面那个不是转义字符? A.\n B.\060 C.\q D.\b 二、错因分析及思考 1.题目看…...
吴恩达深度学习复盘(7)一个简单训练示例
简介 本篇简单讲解简单的神经网络训练。通过回顾逻辑回归模型训练,了解神经网络训练的相关内容。比如训练步骤、损失函数、优化算法以及深度学习库的使用,了解训练过程中的相关概念。 例子 手写数字识别(判断是 0 还是 1)。这是…...
道路坑洼目标检测数据集-665-labelme
文章目录 1.介绍3.标签介绍4.标注工具5.数据集下载 1.介绍 目标:从道路图像中检测坑洼; 应用:检测道路地形和坑洼可实现平稳行驶,小型数据集常常用于学习和学术研究; 详细信息: 665 张图、1740个在坑洼处标…...
提升移动端用户体验:解决输入框被软键盘遮挡的有效方法
解决移动端输入框被软键盘覆盖的问题 在开发移动端网页时,如果页面包含输入框,则可能会遇到输入框被弹出的软键盘遮挡的问题。为了解决这个问题,我们需要理解两种常见的情况以及相应的解决策略。 浏览器未主动聚焦到输入框 现代浏览器和移…...
函数极限常见计算方法集锦
本文非常直接,如标题所见就是一个常见的计算方式极限方法的集锦。 所以内在逻辑性确实不强,主要通过例题的形式阐述。 添项减项 当题目出现了交错的形式便可以考虑添项减项。 一般而言我们会加一项交错项,减一项交错项。 例如出现 A B …...
Tomcat的部署
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和 并发访问用户不是很多的场合下被普遍使用,Tomcat 具有处理HTML页面的功能,它还是一个Servlet和 JSP容器 官网:Apache Tomcat - Welco…...
Ubuntu(CentOS、Rockylinux等)快速进入深度学习pytorch环境
这里写自定义目录标题 安装进入系统(如Ubuntu22.04)安装anacondapip、conda换源pip换源conda换源 安装nvidia安装pytorch环境针对于wsl的优化 安装进入系统(如Ubuntu22.04) docker 、 wsl 、 双系统 、服务器系统 推荐 Ubuntu 20…...
AI 如何帮助我们提升自己,不被替代
在当今快速发展的时代,人工智能(AI)正逐渐渗透到生活的方方面面。许多人担心 AI 会取代人类的工作,然而,AI 更多的是作为一种强大的赋能工具,帮助我们提升自身能力,让我们在工作中更具竞争力。以…...
ROS2 多机时间同步(Chrony配置简明指南)
适用场景: 主机运行 ROS2 Humble(发布 /scan 等),板子运行 ROS2 Foxy(发布 /tf 等),两边通过 ROS_DOMAIN_ID 跨平台通讯。需要保证系统时间对齐,避免 TF 插值失败、建图抖动等问题。…...
C 语言排序算法:从基础到进阶的全面解析一、引言
一、引言 在 C 语言编程领域,排序算法是一项基础且核心的技能。无论是处理海量数据,还是优化程序性能,选择合适的排序算法都至关重要。本文将深入剖析 C 语言中常见的几种排序算法,包括冒泡排序、选择排序、插入排序、希尔排序、…...
蓝桥云客--团队赛
2.团队赛【算法赛】 - 蓝桥云课 问题描述 蓝桥杯最近推出了一项团队赛模式,要求三人组队参赛,并规定其中一人必须担任队长。队长的资格很简单:其程序设计能力值必须严格大于其他两名队友程序设计能力值的总和。 小蓝、小桥和小杯正在考虑报名…...
VBA第三十八期 VBA自贡分把表格图表生成PPT
上一节讲到把数据区域自动生成PPT,这一实例是把图表自动生成PPT。 Sub CopyA11ChartsToPresenta() Dim PP As PowerPoint. Application Dim PPPres As PowerPoint. Presentation Dim PPSlide As PowerPoint. SlideDim i As Integer Shee…...
Linux字符驱动设备开发入门之框架搭建
声明 本博客所记录的关于正点原子i.MX6ULL开发板的学习笔记,(内容参照正点原子I.MX6U嵌入式linux驱动开发指南,可在正点原子官方获取正点原子Linux开发板 — 正点原子资料下载中心 1.0.0 文档),旨在如实记录我在学校学…...
Nextjs15 实战 - React Notes之SidebarNoteList优化和Suspense的使用
current branch 对应如下文档 redis ioredis 本专栏内容均可在Github:notes_02 找到 完整项目使用技术栈: Nextjs15 MySQL Redis Auth Prisma i18n strapi Docker vercel 一、本节目标 实现笔记列表展开回收和 Suspense 的实践 二、修改根…...
第三十章:Python-NetworkX库:创建、操作与研究复杂网络
一、NetworkX库简介 NetworkX是一个强大的Python库,用于创建、操作和研究复杂网络(图)的结构、动态和功能。它支持多种类型的图,包括无向图、有向图、加权图和多重图,并提供了丰富的图论算法和可视化工具。资源绑定附…...
cpp自学 day19(多态)
一、基本概念 同一操作作用于不同的对象,产生不同的执行结果 👉 就像「按F1键」:在Word弹出帮助文档,在PS弹出画笔设置,同一个按键触发不同功能 (1)多态类型 类型实现方式绑定时机静态多态…...
Unity:销毁(Destroy)
Destroy的基本概念 Destroy是Unity提供的一个方法,用于立即或延迟销毁游戏对象(GameObject)或其组件(Component)。它会从场景中移除对象,并释放相关资源(比如内存)。 语法 销毁Ga…...
【C++初阶】模板进阶
目录 模板参数 模板的特化 函数特化 类模板特化 全特化 偏特化 模板分离编译 分离编译 模板的分离编译 为什么模板不支持声明和定义分离呢? 解决方法 模板总结 优点 缺点 模板参数 模板参数分为类型形参和非类型参数 类型形参:出现在模板…...
BN 层的作用, 为什么有这个作用?
BN 层(Batch Normalization)——这是深度神经网络中非常重要的一环,它大大改善了网络的训练速度、稳定性和收敛效果。 🧠 一句话理解 BN 层的作用: Batch Normalization(批归一化)通过标准化每一…...
CNN 里面能自然起到防止过拟合的办法
在 CNN(卷积神经网络)中,其实有 一些结构和机制 天然就具有防止过拟合(overfitting)的作用,不完全依赖额外的正则化手段。 🧠 一、CNN 天然防过拟合的几个原因: 1️⃣ 局部连接&…...
存储基石:深度解读Linux磁盘管理机制与文件系统实战
Linux系列 文章目录 Linux系列前言一、磁盘1.1 初识磁盘1.2 磁盘的物理结构1.3 磁盘的存储结构1.4 磁盘的逻辑结构 二、文件系统2.1 系统对磁盘的管理2.2 文件在磁盘中的操作 前言 Linux 文件系统是操作系统中用于管理和组织存储设备(如硬盘、SSD、USB 等ÿ…...
AI Agent设计模式六:ReAct
概念 :思考-执行循环系统 ✅ 优点:提升任务完成度,适合复杂问题拆解❌ 缺点:执行延迟较高,资源消耗大 from langchain_core.messages import SystemMessage, HumanMessage, ToolMessage, AIMessage from langgraph.pr…...
使用MySQL时出现 Ignoring query to other database 错误
Ignoring query to other database 错误 当在远程连接软件中输入MySQL命令出现该错误 导致错误原因是:登录mysql时账户名没有加上u 如果出现该错误,退出mysql,重新输入正确格式进入即可!...
(三)链式工作流构建——打造智能对话的强大引擎
上一篇:(二)输入输出处理——打造智能对话的灵魂 在前两个阶段,我们已经搭建了一个基础的智能对话,并深入探讨了输入输出处理的细节。今天,我们将进入智能对话的高级阶段——链式工作流构建。这一阶段的目…...
跳跃连接(Skip Connection)与残差连接(Residual Connection)
1. 跳跃连接(Skip Connection)的基本概念 跳跃连接是一种在深度神经网络中广泛应用的技术,它允许信息在网络中跨层直接传递。在传统的神经网络里,每一层的输出仅仅是前一层输出经过特定变换后的结果。而在具备跳跃连接的网络中&a…...
[特殊字符] 通过Postman和OAuth 2.0连接Dynamics 365 Online的详细步骤 [特殊字符]
🌟 引言 在企业应用开发中,Dynamics 365 Online作为微软的核心CRM平台,提供了强大的Web API接口。本文将教你如何通过Postman和OAuth 2.0认证实现与Dynamics 365的安全连接,轻松调用数据接口。 📝 准备工作 工具安装…...