9. 赋值运算符重载

9.1 运算符重载

在 C++ 里,运算符重载能够让自定义类型的对象像内置类型那样使用运算符,这极大地提升了代码的可读性与可维护性。运算符重载本质上是一种特殊的函数,其函数名是 operator 加上要重载的运算符。

下面是运算符重载的一般语法:

返回类型 operator 运算符 (参数列表) {// 函数体
}

运算符重载有一些规则和限制:

  • 不能创建新的运算符,只能重载已有的运算符。

  • 不改变运算符的优先级和结合性。

  • 至少有一个操作数是自定义类型。重载操作符至少有⼀个类类型参数,不能通过运算符重载改变内置类型对象的含义,如:int operator+(int x, int y)

  • .* :: sizeof ?: . 注意以上5个运算符不能重载。

  • 一个类需要重载哪些运算符,是看哪些运算符重载后有意义,比如Date类重载operator-就有意义,但是重载operator+就没有意义。

  • 重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,无法很好的区分。C++规定,后置++重载时,增加一个int形参,跟前置++构成函数重载,方便区分。

  • 重载<<和>>时,需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第⼀个形参位置,第⼀个形参位置是左侧运算对象,调用时就变成了对象<<cout,不符合使用习惯和可读性。重载为全局函数把ostream/istream放到第⼀个形参位置就可以了,第二个形参位置当类类型对象。

#include<iostream>using namespace std;// 编译报错:“operator +”必须⾄少有⼀个类类型的形参
int operator+(int x, int y){return x - y;}class A{public:void func(){cout << "A::func()" << endl;}
};typedef void(A::*PF)(); //成员函数指针类型int main(){// C++规定成员函数要加&才能取到函数指针PF pf = &A::func;A obj;//定义ob类对象temp // 对象调⽤成员函数指针时,使⽤.*运算符(obj.*pf)();return 0;}

9.2 赋值运算符重载

赋值运算符重载是运算符重载的一种特殊情况,它允许我们自定义对象之间的赋值行为。赋值运算符的函数名是 operator=

下面是赋值运算符重载的一般语法:

类名& operator=(const 类名& other) {if (this != &other) {// 执行赋值操作}return *this;
}

这里需要注意几个要点:

  • 返回值类型通常是当前类类型引用类名&,引用返回可以提高效率,这样也可以支持连续赋值,例如 a = b = c
  • 参数通常是 const 类名&,这避免了不必要的拷贝(传值传参会有拷贝),同时保证不会修改传入的对象。
  • 有返回值,且建议写成当前类类型引用,引用返回可以提高效率,有返回值目的是为了支持连续赋值场景。
  • 没有显式实现时,编译器会自动生成一个默认赋值运算符重载,默认赋值运算符重载行为跟默认构造函数类似,对内置类型成员变量会完成值拷贝/浅拷贝(⼀个字节⼀个字节的拷贝),对自定义类型成员变量会调用他的拷贝构造。
class Date
{public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d){cout << " Date(const Date& d)" << endl;_year = d._year;_month = d._month;_day = d._day;}// 传引⽤返回减少拷⻉// d1 = d2;Date& operator=(const Date& d){// 不要检查⾃⼰给⾃⼰赋值的情况if (this != &d){_year = d._year;_month = d._month;_day = d._day;}// d1 = d2表达式的返回对象应该为d1,也就是*this return *this;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;};int main(){Date d1(2024, 7, 5);Date d2(d1);Date d3(2024, 7, 6);d1 = d3;// 需要注意这⾥是拷⻉构造,不是赋值重载// 请牢牢记住赋值重载完成两个已经存在的对象直接的拷⻉赋值// ⽽拷⻉构造⽤于⼀个对象拷⻉初始化给另⼀个要创建的对象Date d4 = d1;return 0;}

9.3 日期类的实现

下面我们来实现一个日期类 Date,并对运算符进行重载:

#pragma once#include<iostream>using namespace std;#include<assert.h>class Date{// 友元函数声明 我们下面马上就会说friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);public:Date(int year = 1900, int month = 1, int day = 1);void Print() const;// 直接定义类里⾯,他默认是
inline // 频繁调⽤int GetMonthDay(int year, int month){assert(month > 0 && month < 13);static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };// 365天 5h + if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){ return 29;}else{return monthDayArray[month];}}bool CheckDate();bool operator<(const Date& d) const;bool operator<=(const Date& d) const;bool operator>(const Date& d) const;bool operator>=(const Date& d) const;bool operator==(const Date& d) const;bool operator!=(const Date& d) const;// d1 += 天数Date& operator+=(int day);Date operator+(int day) const;// d1 -= 天数Date& operator-=(int day);Date operator-(int day) const;// d1 - d2int operator-(const Date& d) const;// ++d1 -> d1.operator++()Date& operator++();// d1++ -> d1.operator++(0)// 为了区分,构成重载,给后置++,强⾏增加了⼀个int形参// 这⾥不需要写形参名,因为接收值是多少不重要,也不需要⽤// 这个参数仅仅是为了跟前置++构成重载区分Date operator++(int);Date& operator--();Date operator--(int);// 流插⼊// 不建议,因为Date* this占据了⼀个参数位置,使⽤d<<cout不符合习惯//void operator<<(ostream& out);private:int _year;int _month;int _day;};// 重载ostream& operator<<(ostream& out, const Date& d);istream& operator>>(istream& in, Date& d);// Date.cpp#include"Date.h"bool Date::CheckDate(){if (_month < 1 || _month > 12|| _day < 1 || _day > GetMonthDay(_year, _month)){return false;}else{return true;}}Date::Date(int year, int month, int day){_year = year;_month = month;_day = day;if (!CheckDate()){cout << "⽇期⾮法" << endl;}}void Date::Print() const{cout << _year << "-" << _month << "-" << _day << endl;}// d1 < d2bool Date::operator<(const Date& d) const{if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){return _day < d._day;}}return false;}// d1 <= d2bool Date::operator<=(const Date& d) const{return *this < d || *this == d;}bool Date::operator>(const Date& d) const{return !(*this <= d);}bool Date::operator>=(const Date& d) const{return !(*this < d);}bool Date::operator==(const Date& d) const{return _year == d._year&& _month == d._month&& _day == d._day;}bool Date::operator!=(const Date& d) const{return !(*this == d);}// d1 += 50// d1 += -50Date& Date::operator+=(int day){if (day < 0){return *this -= -day;}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;if (_month == 13){++_year;_month = 1;}}return *this;}Date Date::operator+(int day) const{Date tmp = *this;tmp += day;return tmp;}// d1 -= 100Date& Date::operator-=(int day) 
{if (day < 0){return *this += -day;}_day -= day;while (_day <= 0){--_month;if (_month == 0){_month = 12;_year--;}// 借上⼀个⽉的天数_day += GetMonthDay(_year, _month);}return *this;}Date Date::operator-(int day) const{Date tmp = *this;tmp -= day;return tmp;}//++d1Date& Date::operator++(){*this += 1;return *this;}// d1++Date Date::operator++(int){Date tmp(*this);*this += 1;return tmp;}Date& Date::operator--(){*this -= 1;return *this;}Date Date::operator--(int){Date tmp = *this;*this -= 1;return tmp;}// d1 - d2int Date::operator-(const Date& d) const{Date max = *this;Date min = d;int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){++min;++n;}return n * flag;}ostream& operator<<(ostream& out, const Date& d){out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;}istream& operator>>(istream& in, Date& d){cout << "请依次输⼊年月日:>";in >> d._year >> d._month >> d._day;if (!d.CheckDate()){cout << "日期⾮法" << endl;}return in;}

大家可以自写测试函数进行自行测试,再此我不过多赘述

10. 取地址运算符重载

10.1 const 成员函数

在 C++ 中,const 成员函数是指那些不会修改对象状态的成员函数。在函数声明和定义时,在参数列表后面加上 const 关键字,就可以将该函数声明为 const 成员函数。

下面是 const 成员函数的一般语法:

返回类型 函数名(参数列表) const {// 函数体
}

const 成员函数有以下几个特点:

  • 只能调用其他的 const 成员函数。
  • const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进⾏修改。const 修饰Date类的Print成员函数,Print隐含的this指针由Date* const this变为const Date* const this

以下是一个示例:

 #include<iostream>using namespace std;class Date{
public:public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// void Print(const Date* const this) constvoid Print() const{cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;};int main(){// 这里非const对象也可以调⽤const成员函数是一种权限的缩⼩Date d1(2024, 7, 5);d1.Print();const Date d2(2024, 8, 5);d2.Print();return 0;}

在上述代码中,getData 函数被声明为 const 成员函数,因此可以被 const 对象调用。

10.2 取地址运算符重载

取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,⼀般这两个函数编译器自动生成的就可以够我们用了,不需要去显示实现。除非⼀些很特殊的场景,比如我们不想让别人取到当前类对象的地址,就可以自己实现⼀份,胡乱返回一个地址。

 class Date{ 
public :Date* operator&(){return this;// return nullptr;}const Date* operator&()const{return this;// return nullptr;}private :int _year ; // 年int _month ; // ⽉int _day ; // ⽇};

11. 友元

11.1 友元的概念

在 C++ 中,封装性是面向对象编程的重要特性之一,它通过访问限定符(publicprivateprotected)来控制类的成员的访问权限。然而,在某些特殊情况下,我们可能需要让一个外部的函数或类能够访问某个类的私有成员。这时,就可以使用友元机制。友元机制提供了一种突破封装性的方式,允许特定的外部函数或类访问另一个类的私有和保护成员。

11.2 友元函数

友元函数是一种在类外部定义的普通函数,但通过在类内部使用 friend 关键字进行声明,使得该函数可以访问类的私有和保护成员。

示例代码

#include <iostream>
class Point {
private:int x;int y;
public:Point(int x = 0, int y = 0) : x(x), y(y) {}// 声明友元函数friend void printPoint(const Point& p);
};// 友元函数的定义
void printPoint(const Point& p) {std::cout << "x: " << p.x << ", y: " << p.y << std::endl;
}int main() {Point p(3, 4);printPoint(p);return 0;
}

在上述代码中,printPoint 函数是 Point 类的友元函数,因此它可以直接访问 Point 类的私有成员 xy

11.3 友元类

友元类是指一个类可以访问另一个类的私有和保护成员。在一个类中使用 friend 关键字声明另一个类为友元类,那么这个友元类的所有成员函数都可以访问该类的私有和保护成员。

示例代码

#include <iostream>
class A {
private:int data;
public:A(int d = 0) : data(d) {}// 声明 B 为 A 的友元类friend class B;
};class B {
public:void accessA(A& a) {std::cout << "Accessing A's data: " << a.data << std::endl;}
};int main() {A a(10);B b;b.accessA(a);return 0;
}

在这个例子中,BA 的友元类,所以 B 类的成员函数 accessA 可以访问 A 类的私有成员 data

11.4 友元的注意事项

  • 友元关系是单向的,即如果 AB 的友元,并不意味着 BA 的友元。
  • 友元关系不具有传递性,即如果 AB 的友元,BC 的友元,并不意味着 AC 的友元。
  • 友元破坏了类的封装性,增加耦合度,使用时需要谨慎(不宜多用)。

12. 类型转换&&static成员

12.1 类型转换

C++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数、
构造函数前面加explicit就不再支持隐式类型转换
比如:

#include<iostream>
using namespace std;
class A
{ 
public:// 构造函数explicit就不再⽀持隐式类型转换// explicit A(int a1)A(int a1):_a1(a1){}//explicit A(int a1, int a2)A(int a1, int a2):_a1(a1),_a2(a2){}void Print(){cout << _a1 << " " << _a2 << endl;}
private:int _a1 = 1;int _a2 = 2;
};
int main()
{// 1构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造aa3// 编译器遇到连续构造+拷⻉构造->优化为直接构造A aa1 = 1;aa1.Print();const A& aa2 = 1;// C++11之后才⽀持多参数转化A aa3 = { 2,2 };return 0;
}

12.2 static成员

直接给出注意的点

  • 用static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进行初始化
  • 静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。
    static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。
  • 静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。
  • 非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
  • 突破类域就可以访问静态成员,可以通过类名::静态成员对象.静态成员来访问静态成员变量和静态成员函数。
  • 静态成员也是类的成员,受public、protected、private访问限定符的限制。
  • 静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表
// 实现⼀个类,计算程序中创建出了多少个类对象?
#include<iostream>
using namespace std;
class A
{ 
public:A(){++_scount;} A(const A& t){++_scount;} ~A(){--_scount;} static int GetACount(){return _scount;}
private:// 类⾥⾯声明static int _scount;
};
// 类外⾯初始化
int A::_scount = 0;int main()
{cout << A::GetACount() << endl;A a1, a2;A a3(a1);cout << A::GetACount() << endl;cout << a1.GetACount() << endl;// 编译报错:error C2248: “A::_scount”: ⽆法访问 private 成员(在“A”类中声明)//cout << A::_scount << endl;return 0;
}

13. 内部类

如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独立的类,跟定义在全局相比,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类。

  • 内部类默认是外部类的友元类。
  • 内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使用,那么可以考虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其他地方都用不了。
#include<iostream>
using namespace std;
class A
{ 
private:static int _k;int _h = 1;
public:class B // B默认就是A的友元{ public:void foo(const A& a){cout << _k << endl; //OKcout << a._h << endl; //OK}};
};
int A::_k = 1;int main()
{cout << sizeof(A) << endl;A::B b;A aa;b.foo(aa);return 0;
}

这个题相信大家都不陌生,然而如果不让你使用循环你该怎么做呢???
求1+2+3+…+n_牛客

class Solution {private:static int ret;static int i;class Sum{public:Sum(){ret+=i;++i;}};
public:int Sum_Solution(int n) {Sum a[n];return ret;}
};
int Solution::ret=0;
int Solution::i=1;

是不是使用内部类的时候初始化直接求出来了哦,你就说这个方法巧不巧妙

14. 匿名对象

匿名对象是指没有名字的对象,它通常在创建后立即使用,使用完后就会被销毁。匿名对象可以用于临时传递参数或者调用函数。
匿名对象生命周期只在当前一行,一般临时定义一个对象当前用一下即可,就可以定义匿名对象。
比如:

#include <iostream>
class Test {
public:Test() {std::cout << "Constructor called" << std::endl;}~Test() {std::cout << "Destructor called" << std::endl;}void print() {std::cout << "Print function called" << std::endl;}
};int main() {// 创建匿名对象并调用 print 函数Test().print();//使用完后立即销毁return 0;
}

15. 对象拷贝时的编译器优化 *

  • 现代编译器会为了尽可能提高程序的效率,在不影响正确性的情况下会尽可能减少一些传参和传参过程中可以省略的拷贝。
  • 如何优化C++标准并没有严格规定,各个编译器会根据情况自行处理。当前主流的相对新一点的编译器对于连续⼀个表达式步骤中的连续拷贝会进行合并优化,有些更新更"激进"的编译还会进行跨行跨表达式的合并优化。

在此以VS为例简要说明

#include<iostream>
using namespace std;
class A
{ 
public:A(int a = 0):_a1(a){cout << "A(int a)" << endl;} A(const A& aa):_a1(aa._a1){cout << "A(const A& aa)" << endl;} A& operator=(const A& aa){cout << "A& operator=(const A& aa)" << endl;if (this != &aa){_a1 = aa._a1;} return *this;
} ~A(){cout << "~A()" << endl;}
private:int _a1 = 1;
};
void f1(A aa)
{}
A f2()
{A aa;return aa;
} 
int main()
{// 传值传参A aa1;f1(aa1);cout << endl;// 隐式类型,连续构造+拷⻉构造->优化为直接构造f1(1);// ⼀个表达式中,连续构造+拷⻉构造->优化为⼀个构造f1(A(2));cout << endl;cout << "***********************************************" << endl;// 传值返回// 返回时⼀个表达式中,连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 (vs2019)// ⼀些编译器会优化得更厉害,进⾏跨⾏合并优化,直接变为构造。(vs2022)f2();cout << endl;// 返回时⼀个表达式中,连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 (vs2019)// ⼀些编译器会优化得更厉害,进⾏跨⾏合并优化,直接变为构造。(vs2022)A aa2 = f2();cout << endl;// ⼀个表达式中,连续拷⻉构造+赋值重载->⽆法优化aa1 = f2();cout << endl;return 0;
}

如果你看到了这,那么恭喜你,关于类与对象的大部分内容基本上说清楚了,至于其他的,咱们在后面慢慢说,期待与你的下次相遇~~~
在这里插入图片描述

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

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

相关文章

【深度学习-Day 6】掌握 NumPy:ndarray 创建、索引、运算与性能优化指南

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…

工程师 - 汽车分类

欧洲和中国按字母对汽车分类&#xff1a; **轴距**&#xff1a;简单来说&#xff0c;就是前轮中心点到后轮中心点之间的距离&#xff0c;也就是前轮轴和后轮轴之间的长度。根据轴距的大小&#xff0c;国际上通常把轿车分为以下几类&#xff08;德国大众汽车习惯用A\B\C\D分类&a…

[低代码 + AI] 明道云与 Dify 的三种融合实践方式详解

随着低代码平台和大语言模型工具的不断发展,将企业数据与智能交互能力融合,成为提高办公效率与自动化水平的关键一步。明道云作为一款成熟的低代码平台,Dify 则是一个支持自定义工作流的开源 LLM 应用框架。两者结合,可以实现灵活、高效的智能化业务处理。 本文将详解明道…

鼠标悬浮特效:常见6种背景类悬浮特效

鼠标悬浮特效&#xff1a;常见6种背景类悬浮特效 前言背景闪现效果预览代码展示 元素阴影效果预览代码展示 元素悬浮阴影效果预览代码展示 元素上浮阴影效果预览代码展示 元素边框阴影效果预览代码展示 元素卷角效果预览代码展示 结语 前言 在之前的文章中&#xff0c;我们介绍…

[人机交互]理解与概念化交互

零.本章重点&#xff08;理解和分析用户问题&#xff09; – 解释“问题空间”的概念和含义 – 解释如何概念化交互 – 描述什么是概念模型 – 讨论将界面隐喻作为概念模型的利弊 – 讨论界面具体化和抽象化各自的优缺点 – 概述概念设计和实际设计的关系 一.理解问题空间 简单…

9.城市基础设施更新工程

9.1 道路改造施工 9.1.1 道路改造施工内容 沥青、水泥混凝土、砌块路面、人行步道、绿化照明、附属设施、交通标志、沥青路面材料的再生利用 9.1.2 道路改造施工技术 1.沥青路面病害及微表处理 1.病害处理 裂缝处理 10mm以内专业灌缝材料或热沥青灌缝、潮湿时乳化沥青灌封…

Milvus(11):动态字段、可归零和默认值

1 动态字段 Collections 的 Schema 中定义的所有字段都必须包含在要插入的实体中。如果希望某些字段是可选的&#xff0c;可以考虑启用动态字段。 1.1 概述 在 Milvus 中&#xff0c;可以通过设置 Collections 中每个字段的名称和数据类型来创建 Collections Schema。向 Schem…

LeetCode41☞缺失的第一个正数

关联LeetCode题号41 本题特点 数组&#xff0c;哈希表 本题思路 找缺失的最小正数&#xff0c;看举例说明缺失的正数&#xff0c;一种情况是连续的最小的正数&#xff0c;一种是缺失连续但不是最小的正数验证数组内数组是否连续&#xff0c;可以通过 nums[i]1 是否存nums组…

补题( Convolution, 二维卷积求输出矩阵元素和最大值)

来源&#xff1a;https://codeforces.com/gym/105231/problem/H 题目描述&#xff1a; 一、题目分析 本题涉及深度学习中的二维卷积操作。给定一个nm的二维输入矩阵I和一个kl的核矩阵K &#xff0c;通过特定公式计算得到(n - k 1)(m - l 1)的输出矩阵O &#xff0c;要求在…

【Java ee初阶】多线程(7)

一、线程池 线程池的一些参数&#xff1a; corePoolSize&#xff1a;核心线程数量 maximumPoolSize:核心线程数量临时线程数量 上述是“java 的线程池策略”&#xff08;其他语言&#xff0c;其他库的线程池可能不同&#xff09; keepAliveTime :临时线程的存活时间.临时线程…

Linux 常用指令详解

Linux 操作系统中有大量强大的命令行工具&#xff0c;下面我将分类介绍一些最常用的指令及其用法。 ## 文件与目录操作 ### 1. ls - 列出目录内容 ls [选项] [目录名] 常用选项&#xff1a; - -l&#xff1a;长格式显示&#xff08;详细信息&#xff09; - -a&#xff1a;显…

uv安装及使用

windows安装参考&#xff1a; 什么是python uv&#xff0c;如何在windows上安装uv&#xff0c;基础的用法有哪些&#xff1f;_windows安装uv-CSDN博客 https://zhuanlan.zhihu.com/p/6776864377 使用方式 方式1&#xff1a; 创建uv虚拟环境->激活环境->安装依赖&…

C#实现Socket通信:基于TCP/IP协议的网络编程

TCP/IP网络模型 最上层的是应用层&#xff0c;也就是我们日常可以接触到的&#xff0c;它会给数据添加对应的头部&#xff0c;并传输给传输层&#xff0c;应用层是我们日常会接触到的&#xff0c;比如HTTP&#xff0c;FTP&#xff0c;Telnet&#xff0c;DNS&#xff0c;SMTP。…

哈希算法、搜索算法与二分查找算法在 C# 中的实现与应用

在计算机科学中&#xff0c;哈希算法、搜索算法和二分查找算法是三个非常基础且常用的概念。它们分别在数据存储、数据查找、以及高效检索等场景中起着至关重要的作用。在 C# 中&#xff0c;这些算法的实现和使用也十分简便。本文将详细讲解这三种算法的原理、应用以及 C# 中的…

AI日报 · 2025年5月05日|雅诗兰黛与微软合作成立 AI 创新实验室,加速美妆产品研发与营销

1、苹果与 Anthropic 深化合作&#xff0c;内部测试 AI 驱动的新版 Xcode 据多方报道&#xff0c;苹果公司正与人工智能初创公司 Anthropic 合作&#xff0c;开发集成 AI 功能的新一代 Xcode 开发平台。该平台旨在利用 Anthropic 强大的 Claude Sonnet 模型&#xff0c;为开发…

python celery框架结合django的使用

学习目标&#xff1a; 通过文章了解celery的运行机制以及如何结合django去使用 熟悉celery的运行原理属性celery在django项目当中的配置如何启动运行celery框架 学习内容&#xff1a; 熟悉celery的运行原理&#xff0c;简单来说 Celery 是一个“任务排队机后台处理器”。帮你…

滑动窗口leetcode 904

代码&#xff1a; class Solution { public:int totalFruit(vector<int>& fruits) {int n fruits.size();unordered_map<int,int> window_type_count;int left 0;int ans 0;for(int right 0; right <n;right){while(window_type_count.size() 2 &&…

用可视化学习逆置法

1.逆置法思路 目标&#xff1a;将这个彩色数组向右旋转3步 &#x1f534;1 → &#x1f7e0;2 → &#x1f7e1;3 → &#x1f7e2;4 → &#x1f535;5 → &#x1f7e3;6 → ⚪7我们希望得到 &#x1f535;5 → &#x1f7e3;6 → ⚪7 → &#x1f534;1 → &#x1f7e0;…

Cisco Packet Tracer 选项卡的使用

目录 设备Config选项卡的使用 Realtime and Simulation模式&#xff08;数据包跟踪与分析&#xff09; 设备Desktop选项卡的使用 设备Config选项卡的使用 Hostname NVRAM Startup Config----Load 加载 INTERFACE 点击on Save 如果&#xff0c;不把Running Config保存为Sta…

pyqt写一个单片机配置界面

已经实现以下功能 1.可以选择单片机架构 2.选择完单片机架构后第二个框可以选择常见单片机型号 3.选择完常见单片机型号后第三个框可以选择内部资源如adc等&#xff08;可以选择多个内部资源&#xff09;4.选择完内部资源如adc等&#xff08;可以选择多个内部资源&#xff09;后…