C++类和对象:拷贝构造函数和运算符重载
目录
一. 拷贝构造函数
1.1 什么是拷贝构造函数
1.2 编译器默认生成的拷贝构造函数
1.3 拷贝构造函数特性总结
二. 运算符重载
2.1 运算符重载概述
2.2 比较运算符重载(> >= == < <=)
2.2.1 >运算符的重载
2.2.2 ==运算符的重载
2.2.3 >=运算符的重载
2.2.4 <运算符的重载
2.2.5 <=运算符的重载
2.3 加减相关运算符的重载(+= 、++、-=、--、+、-)
2.3.1 +=运算符的重载
2.3.2 +运算符的重载
2.3.3 -=运算符的重载
2.3.4 -运算符重载
2.3.5 ++运算符的重载
2.3.6 --运算符的重载
2.4 赋值运算符重载函数
2.4 取地址及const取地址操作符重载
2.4.1 const成员
2.4.2 &操作符的重载
一. 拷贝构造函数
1.1 什么是拷贝构造函数
拷贝构造函数,是C++类的六个默认构造函数之一,其完成的功能是通过一个已有的类对象,创建并初始化一个新的同类类对象。
拷贝构造函数的函数名与类名相同,有且只有一个类型为本类对象引用的参数,没有返回值。且拷贝构造函数唯一的参数一般使用const修饰。
演示代码1.1以日期类为例,首先创建了一个类对象d1,再通过类对象d1创建了一个新的类对象d2,调用Print成员函数打印类中成员变量的值,可以看到,d1和d2中成员变量值相同。
调用拷贝构造函数创新新对象的语法为:类名 拷贝构造函数名(&对象名)。
演示代码1.1:
#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;class Date
{
public:Date(int year, int month, int day) //构造函数{_year = year;_month = month;_day = day;}Date(const Date& d) //拷贝构造函数{_year = d._year;_month = d._month;_day = d._day;}void Print() //类成员变量打印函数{cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 2, 28); //创建类对象,调用默认构造函数Date d2(d1); //调用拷贝构造函数创建类对象d1.Print();d2.Print();return 0;
}

警告:拷贝构造函数的参数必须是引用,不可以是值,因为这会引发无穷递归。
从图1.2中可以看出,当采用对象值作为拷贝构造函数的参数时,每次创建形参都会引发一次拷贝构造函数的调用,程序会一直调用调用拷贝构造函数,永远不会执行函数体内部的语句。当然,某些编译器会将值作为拷贝构造函数的参数的错误检查出来。

1.2 编译器默认生成的拷贝构造函数
跟构造函数和析构函数一样,如果用户不显示地定义拷贝构造函数,那么编译器就会自动生成拷贝构造函数。编译器默认生成的拷贝构造函数完成的操作是将一个已存在的类对象的内容逐字节拷贝到新创建的对象中,这种拷贝方式叫浅拷贝(值拷贝)。
演示代码1.3的日期类Date中不显示定义拷贝构造函数,运行程序,用d1拷贝构造d2,可以看到,d1和d2的成员变量值依旧相同,这证实了编译器会生成默认的拷贝构造函数。
演示代码1.2:
class Date
{
public:Date(int year = 1, int month = 1, int day = 1) //构造函数{_year = year;_month = month;_day = day;}void Print() //类成员变量打印函数{cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 2, 28); //创建类对象,调用默认构造函数Date d2(d1); //调用编译器默认生成的拷贝构造函数创建类对象d1.Print();d2.Print();return 0;
}

问题:根据演示代码1.1和1.2的运行结果,用户显示定义的拷贝构造函数和编译的自动生成的拷贝构造函数完成一样的操作,那是否可以认为,用户显示定义的拷贝构造函数没有什么价值呢?
答案显然是否定的。
对于上面代码中定义的日期类,确实可以使用编译器默认生成的拷贝构造函数。但是,对于那些类对象涉及动态资源申请的类,就不可以使用编译器默认生成的拷贝构造函数。
演示代码1.3中定义了栈类Stack,其中成员变量int* _a用于动态资源申请,在类对象销毁时,编译器会自动调用析构函数~Stack()释放动态开辟的内存空间,如果此时用s1拷贝构造s2,那么s1和s2中的_a就会指向同一块内存空间,对s1和s2两次调用析构函数会对同一块动态开辟的内存空间多次释放,造成程序崩溃。这种情况就必须有用户显示定义拷贝构造函数,实现深拷贝。
演示代码1.3:
class Stack
{
public:Stack(int capacity = 10) //构造函数 {_a = (int*)malloc(capacity * sizeof(int));if (nullptr == _a){printf("malloc fail\n");exit(-1);}_capacity = capacity;_top = 0;}~Stack() //析构函数,释放动态开辟的内存空间{free(_a);_a = nullptr;_capacity = _top = 0;}void Push(int x) //压栈函数{_a[_top] = x;_top++;}private:int* _a;int _top;int _capacity;
};int main()
{Stack s1; s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);s1.Push(5); //将1、2、3、4、5压入栈中Stack s2(s1); //调用编译器默认生成的拷贝构造函数return 0; //程序结束前两次调用析构函数
}

1.3 拷贝构造函数特性总结
- 拷贝构造函数的函数名与类名相同。
- 拷贝构造函数是构造函数的一种重载形式。
- 拷贝构造函数没有返回值。
- 拷贝构造函数的参数有且只有一个,类型为本类对象的引用。
- 不能将值作为拷贝构造函数形参的类型,否则会引发无穷递归。
- 如果用户不显示定义拷贝构造函数,那么编译器就会默认生成拷贝构造函数。
- 对于存在动态资源申请的类,不可以使用编译器自动生成的拷贝构造函数。
二. 运算符重载
2.1 运算符重载概述
C++不允许直接对类对象使用运算符,但是,有些时候我们需要对类对象的成员进行相关操作,如:比较两个日期的先后(判断d1 > d2是否成立)、计算当天之后的第n天的日期(d2 = d1 + day)。为了增强程序的可读性,C++引入了运算符重载。
运算符重载是具有特殊函数名的函数,其具有一般函数公有的返回值、参数列表和函数名。(注意区分,构造函数、析构函数和拷贝构造函数没有返回值)。
运算符重载函数原型:返回值类型 operator运算符(参数列表)。
关于运算符重载的几点注意事项:
- 不能通过operator后接非运算符来创建新操作符,如operator$、operator@ 。
- 运算符必须有一个一个类类型参数。
- 不能改变运算符原本的含义。
- 参数列表的参数个数必须与运算符的操作数个数相同。
- 有五个操作符(sizeof、::、. 、.* 、?:)不能进行重载。
特别注意:在类对象中定义和声明运算符重载,会存在一个隐含的this指针作为一个参数,this指针为运算符重载函数的第一个参数。
对于有两个操作数的运算符,运算符重载函数的第一个参数为左操作数,第二个参数为右操作数。
本章以日期类为例,对各种运算符的重载进行实现
演示代码2.1:(日期类成员变量及成员函数声明)
class Date
{
public:Date(int year = 0, int month = 1, int day = 1); //默认构造函数int GetMonthDay(int year, int month); //月份天数获取函数void Print(); //日期打印函数//1.比较类操作bool operator>(Date& d);bool operator>=(Date& d);bool operator==(Date& d);bool operator<(Date& d);bool operator<=(Date& d);//2.加减法类操作Date& operator+=(int day); //日期加等函数Date operator+(int day); //日期加法函数//前置++和后置++重载//后置++中采用一个int型的占位参数,用于表示后置Date& operator++();Date operator++(int); Date& operator-=(int day); //日期减等函数Date operator-(int day); //日期减法函数Date& operator--(); //日期自减函数(前置)Date operator--(int); //日期自减函数(后置)//日期间隔计算int operator-(Date& d);//星期打印函数void WeekPrint();private:int _year;int _month;int _day;
};
2.2 比较运算符重载(> >= == < <=)
我们只需要实现>和==操作符的重载,那么>= <= <就都可以通过复用>和==运算符重载函数来实现重载。
2.2.1 >运算符的重载
依次比较this指针指向的类的年、月、日是否大于被比较对象即可。
bool Date::operator>(Date& d) //判断大于
{if (_year > d._year){return true;}else if (_year == d._year && _month > d._month){return true;}else if (_year == d._year && _month == d._month && _day > d._day){return true;}else{return false;}
}
2.2.2 ==运算符的重载
年月日均相等返回值为true,否则为false。
bool Date::operator==(Date& d)
{return (_year == d._year) && (_month == d._month) && (_day == d._day);
}
2.2.3 >=运算符的重载
d1>d2和d1==d2其中之一成立即d1>=d2成立,*this代表类对象d1。
bool Date::operator>=(Date& d)
{return (*this > d) || (*this == d);
}
2.2.4 <运算符的重载
d1>d2 和 d1==d2 均不成立即 d1<d2 成立。
bool Date::operator<(Date& d)
{return !((*this > d) || (*this == d));
}
2.2.5 <=运算符的重载
d1>d2 和 d1==d2 其中之一成立即d1<=d2成立。
bool Date::operator<=(Date& d)
{return (*this < d) || (*this == d);
}
2.3 加减相关运算符的重载(+= 、++、-=、--、+、-)
2.3.1 +=运算符的重载
对日期类进行+=操作,就是获取当前日期再过day天后的日期。其计算方式为在当前_day上加day,如果大于当前_month天数就向_month进位,如果_month大于12就向年_year进位。
int Date::GetMonthDay(int year, int month)
{static int MonthDayArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };int day = MonthDayArray[month];//判断闰年,2月天数+1if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){day += 1;}return day;
}Date& Date::operator+=(int day) //日期加等函数
{_day += day;int MonthDay = 0;while (_day > (MonthDay = GetMonthDay(_year, _month))){_day -= MonthDay;_month++; //天数大于当前月份天数就向月进位if (_month == 13) //向年进位{_month = 1;_year++;}}return *this;
}
2.3.2 +运算符的重载
+运算符不改变被加数的值,+=运算符改变被加数的值,+仅返回做加法后的值,不改变被加数本身。因此我们只需要拷贝构造一份*this对象ret,然后对ret执行+=操作即可。
Date Date::operator+(int day) //日期加法
{Date ret(*this); //调用拷贝构造函数,创建返回值ret += day;return ret;
}
2.3.3 -=运算符的重载
计算当前日期向前day天的日期。首先让_day -= day,如果_day<0,就向月借位,如果_month==0成立,就向年借位,直到_day>0终止。
Date& Date::operator-=(int day) //日期减等函数
{_day -= day;while (_day <= 0){_month--; //如果当前天数小于0,向月借位if (_month == 0) //月为0向年借位{_year--;_month = 12;}_day += GetMonthDay(_year, _month); //日期更新}return *this;
}
2.3.4 -运算符重载
与+运算符类似,-运算符不改变被减数的值,-=运算符改变被减数的值,-仅返回做减法后的值,不改变被减数本身。因此我们只需要拷贝构造一份*this对象ret,然后对ret执行-=操作即可。
Date Date::operator-(int day) //日期减法函数
{Date ret(*this); //拷贝构造创建返回值ret -= day;return ret;
}
2.3.5 ++运算符的重载
++运算符分为前置++和后置++,C++通过引入一个int型的占位参数来区分后置++和前置++,后置++需要占位参数。
- 前置++函数声明:Date& operator++()
- 后置++函数声明:Date& operator++(int)
Date& Date::operator++() //日期前置++
{(*this) += 1;return *this;
}Date Date::operator++(int) //日期后置++
{Date ret(*this);(*this) += 1;return ret;
}
2.3.6 --运算符的重载
--与++类似,需要一个int型的占位参数区分前置和后置--。
- 前置--函数声明:Date& operator--()
- 后置--函数声明:Date& operator--(int)
Date& Date::operator--() //日期自减函数(前置)
{(*this) -= 1;return *this;
}Date Date::operator--(int) //日期自减函数(后置)
{Date ret(*this);(*this) -= 1;return ret;
}
2.4 赋值运算符重载函数
赋值运算符重载函数为C++类的六个默认成员函数之一,如果用户不显示定义,那么编译器就会自动生成赋值运算符重载函数。赋值运算符重载函数的返回值类型为类对象的引用,参数有且只有一个,类型也为类对象的引用。
- 函数参数类型:const 类名&
- 函数返回值类型:类名&
- 返回值:*this -- 为了满足=运算符可以连续赋值的特性
- 系统自动生成的赋值函数执行的操作为逐字节赋值
演示代码2.2中显示定义了赋值运算符重载函数,并在主函数中执行连续赋值操作,观察程序运行结果,d1、d2、d3都被赋予了d1的值,可见连续赋值成功。
演示代码2.2:
class Date //日期类
{
public:Date(int year = 0, int month = 1, int day = 1) //默认构造函数{_year = year;_month = month;_day = day;}//赋值运算符重载函数Date& operator=(const Date& date){_year = date._year;_month = date._month;_day = date._day;return *this;}void Print() //日期打印函数{cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 2, 25);Date d2(2023, 2, 15);Date d3;d3 = d2 = d1; cout << "d1: ";d1.Print();cout << "d2: ";d2.Print();cout << "d3: ";d3.Print();return 0;
}

警告:赋值运算符重载函数只能在类的内部定义,不能在类的外部定义为全局函数。
这是因为:如果用户不再类内部显示定义赋值运算符重载函数,那么编译器就会默认生成一个赋值运算符重载函数,这样编译器自动生成的赋值运算符重载函数和用户在类外部自定义的赋值运算符重载函数就会发生冲突。
2.4 取地址及const取地址操作符重载
2.4.1 const成员
假设定义一个const属性的类对象const Date d1,那么如果直接调用d1.Print()会发生报错。这是因为,隐含的this指针参数类型为Date* const this,而&d1的类型为const Date* const,传参时存在权限放大问题。这时,只需要在Print函数的声明后面添加const即可,这里的const的功能是将this指针的参数类型由Date* const转变为const Date* const。
//head.h
#pragma once
#include<iostream>
using namespace std;class Date
{
public:Date(int year = 1, int month = 1, int day = 1);//如果不用const对成员函数进行修饰,那么就无法打印const date的类对象//const修饰改变this指针的类型//Date* const this -> const Date* const thisvoid Print() const; //const成员函数private:int _year;int _month;int _day;
};//Date.cpp
#include "head.h"
Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}void Date::Print() const //const成员函数
{cout << _year << "-" << _month << "-" << _day << endl;
}//test.cpp
#include "head.h"
int main()
{const Date d1(2023, 2, 28);d1.Print(); //调用const成员函数 2023-2-28return 0;
}
2.4.2 &操作符的重载
&操作符重载函数分为对普通对象取地址和对const对象取地址,一般不需要用户来实现。
演示代码2.3:
//如果用户不自定义,那么编译器会自动生成取地址运算符重载操作符
//取地址重载一般不会由用户自主实现
class Date
{
public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date* operator&() //普通对象的取地址操作符运算重载{return this;}const Date* operator&() const //对于const对象的取地址运算符重载{return this;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 2, 27);cout << &d1 << endl;const Date d2(2023, 2, 28);cout << &d2 << endl;return 0;
}

相关文章:

C++类和对象:拷贝构造函数和运算符重载
目录 一. 拷贝构造函数 1.1 什么是拷贝构造函数 1.2 编译器默认生成的拷贝构造函数 1.3 拷贝构造函数特性总结 二. 运算符重载 2.1 运算符重载概述 2.2 比较运算符重载(> > < <) 2.2.1 >运算符的重载 2.2.2 运算符的重载 2.…...

【IntelliJ IDEA】idea plugins搜索不出来,如何找到插件的解决方案
一、背景描述安装好IDEA后,想下载一些插件来使用,因为IDEA非常方便的一点就是插件使用非常的方便,但是经常会发现进入到插件市场无法搜索到插件的情况,这个时候就有点烦人了。那么怎么解决这个问题呢?以下会把我能想到…...

移动端自动化测试(一)appium环境搭建
自动化测试有主要有两个分类,接口自动化和ui自动化,ui自动化呢又分移动端的和web端的,当然还有c/s架构的,这种桌面程序应用的自动化,使用QTP,只不过现在没人做了。 web自动化呢,现在基本上都是…...

5 逻辑回归及Python实现
1 主要思想 分类就是分割数据: 两个条件属性:直线;三个条件属性:平面;更多条件属性:超平面。 使用数据: 5.1,3.5,0 4.9,3,0 4.7,3.2,0 4.6,3.1,0 5,3.6,0 5.4,3.9,0 . . . 6.2,2.9,1 5.1,2.5…...

技术干货 | Modelica建模秘籍之状态变量
在很多领域都有“系统”这个概念,它描述的往往是一些复杂关系的总和。假如我们将系统看做一个黑箱,那么,在系统的作用下,外界的输入有时会产生令人意想不到的输出,“蝴蝶效应”就是其中的典型案例。图1 一只南美洲亚马…...
LeetCode 2574. 左右元素和的差值
给你一个下标从 0 开始的整数数组 nums ,请你找出一个下标从 0 开始的整数数组 answer ,其中: answer.length nums.length answer[i] |leftSum[i] - rightSum[i]| 其中: leftSum[i] 是数组 nums 中下标 i 左侧元素之和。如果不…...

rollup环境配置
VUE2.x源码学习笔记 1. rollup环境配置 首先在VScode中新建文件夹vue_sc,然后终端打开定位到打开的文件夹,输入“npm init -y”初始化配置项,运行成功之后文件夹新增package.json文件 继续在终端运行"npm install babel/preset-env ba…...

二分查找与二分答案、递推与递归、双指针、并查集和单调队列
二分查找与二分答案 文章目录二分查找与二分答案应用总结例题木材加工题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示数据规模与约定思路代码递归与递推应用总结[NOIP2003 普及组] 栈题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示思…...

如何进行域名购买,获取免费ssl证书,使用springboot绑定ssl证书
前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注一下!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!让我们在成长的道路上互相学习&#…...

LabVIEW网络服务安全2
LabVIEW网络服务安全2在客户端应用程序中创建签名对请求进行签名要求您具有能够从客户端的编程语言调用的MD5摘要算法以及SHA256加密摘要算法的实现。这两种算法通常都可用于大多数平台。还需要:1. 要使用的HTTP方法的字符串(“GET”、“POST”、“PUT”…...

java动态代理
目录儿一、代理模式的作用二、实现代理的方式三、动态代理的实现3.1 jdk动态代理3.2 cglib动态代理一、代理模式的作用 功能增强: 基于某个功能,再增加一些功能。 (比如目标类只负责核心功能,其他附属功能通过代理类完成。代理类的方法名与目…...

Python 简单可变、复杂可变、简单不可变、复杂不可变类型的copy、deepcopy的行为
copy模块:copy:浅拷贝deepcopy:深拷贝简单可变类型、复杂可变的copy()、deepcopy():简单不可变、复杂不可变类型的copy()、deepcopy():结论:对于简单类型的可变类型copy是深拷贝,改变了该拷贝变…...

QML Item
在QML中所有的可视项目都继承自Item,虽然Item本身没有可视化的外观,但它定义了可视化项目的所有属性。 Item可以作为容器使用: Item{Rectangle{id:retc}Rectangle{id:retc1}Rectangle{id:retc2}Rectangle{id:retc3}} item拥有children属性…...

使用xca工具生成自签证书
本文使用 xca 生成自签证书。 概述 之前使用 openssl 生成证书,在 golang 中测试,发现客户端连接失败,经查发现是Subject Alternative Name不支持导致的。因虚拟机 openssl 版本较低,有个功能无法实现,且升级麻烦&…...

Unity IOS 通过命令行导出IPA
新建一个文件然后输入如下内容 #!/usr/bin/env sh /Applications/Unity/Hub/Editor/2020.1.5f1c1/Unity.app/Contents/MacOS/Unity -quit -batchmode -projectPath /Users/zyt/Test -executeMethod Test.BuildEditor.BuildApp cd /Users/zyt/Test/Xcode/unity-xcode xcodebuil…...

「架构」全链路异步模式
总结自尼恩的全链路异步:网关纯异步化网关层的特点:不需要访问业务数据库只做协议转换和流量转发特点是 IO 密集型,特别适合纯异步的架构,可以极大的节省资源。如何进行网关异步化?使用高性能的通信框架Nettyÿ…...

CleanMyMac4.20最新版新增功能及电脑清理垃圾使用教程
CleanMyMac4.20作为知名的Mac清理工具,仅需一键即可快速而安全地清理系统垃圾,释放磁盘空间,因此一直深受Mac用户的喜爱。在不断更新的版本中,CleanMyMac已经不仅仅满足于只做简单的Mac清理工具,而是为Mac用户提供更多…...

Vue2的tsx开发入门完全指南
本篇文章尽量不遗漏重要环节,本着真正分享的心态,不做标题党 下面进入正题: 由于现在vue的官方脚手架已经非常完善我们就不单独配置webpack了,节省大量的时间成本。 首先使用vue/cli创建一个vue模版项目(记得是vue/…...

GLSL shader学习系列1-Hello World
这是GLSL shader系列第一篇文章,本文学习目标: 安装编辑工具编写hello world程序 安装插件 我使用VSCode编写shader代码,在VSCode上有两个好用的插件需要先装一下: Shader languages support for VS Code glsl-canvas…...

Codeforces Round #851 (Div. 2)(A~D)
A. One and Two给出一个数组,该数组仅由1和2组成,问是否有最小的k使得k位置的前缀积和后缀积相等。思路:计算2个数的前缀和即可,遍历判断。AC Code:#include <bits/stdc.h>typedef long long ll; const int N 1…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...