【C++】类的默认成员函数下(内含日期类的实现)

【C++】类的默认成员函数下(内含日期类的实现)

文章目录

4.拷贝构造函数

如果一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数也叫做拷贝构造函数,也就是说拷贝构造是一个特殊的构造函数。

拷贝构造的特点:

1.拷贝构造函数是构造函数的一个重载(无返回值)。

2.拷贝构造函数的第一个参数必须是当前类类型对象的引用(最好加上const,防止权限放大的问题),使用传值方式编译器直接报错,因为语法逻辑上会引发无穷递归调用。 拷贝构造函数也可以多个参数,但是第一个参数必须是类类型对象的引用,后面的参数必须有缺省值



3.C++规定自定义类型对象进行拷贝行为必须调用拷贝构造,所以这里自定义类型传值传参和传值返回都会调用拷贝构造函数。

4.若未显式定义拷贝构造,编译器会自动生成拷贝构造函数。自动生成的拷贝构造对内置类型成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的拷贝构造。

5.像Date这样的类成员变量全是内置类型且没有指向什么资源,编译器自动生成的拷贝构造就可以完成需要的拷贝,所以不需要我们显示实现拷贝构造

像Stack这样的类,虽然也都是内置类型,但是_a指向了资源(动态分配的空间),编译器自动生成的拷贝构造完成的值拷贝/浅拷贝会有两个缺点(1)一个对象的修改,会影响另一个对象(比如给Stack st2拷贝Stack st1的内容,如果对st1出栈/入栈操作,会影响st2)

(2)析构时,释放两次空间(st2释放_a指向的空间,st1会再次释放)

所以需要我们自己实现深拷贝(对指向的资源也进行拷贝)。

像MyQueue这样的类型内部主要是自定义类型Stack成员,编译器自动生成的拷贝构造会调用Stack的拷贝构造,也不需要我们显示实现MyQueue的拷贝构造

这里还有一个小技巧,如果一个类显示实现了析构并释放资源(说明有资源需要显式释放),那么它就需要显式写拷贝构造,否则就不需要

6.传值返回会产生一个临时对象调用拷贝构造,传值引用返回,返回的是返回对象的别名(引用),没有产生拷贝。

但是如果返回对象是一个当前函数局部域的局部对象,函数结束就销毁了,那么使用引用返回是有问题的,这时的引用相当于一个野引用,类似一个野指针一样。传引用返回可以减少拷贝,但是一定要确保返回对象,在当前函数结束后还在,才能用引用返回。
#include<iostream>usingnamespace std;classDate{public:Date(int year =1,int month =1,int day =1){ _year = year; _month = month; _day = day;}// 编译报错:error C2652: “Date”: 非法的复制构造函数: 第一个参数不应是“Date”//Date(Date d)Date(const Date& d){ _year = d._year; _month = d._month; _day = d._day;}//用指针也可以,但是这只是一个普通的构造函数,不是拷贝构造函数Date(Date* d){ _year = d->_year; _month = d->_month; _day = d->_day;}voidPrint(){ cout << _year <<"-"<< _month <<"-"<< _day << endl;}private:int _year;int _month;int _day;};voidFunc1(Date d){ cout <<&d << endl; d.Print();}// Date Func2() Date&Func2(){ Date tmp(2024,7,5); tmp.Print();return tmp;}intmain(){ Date d1(2024,7,5);//C++规定自定义类型对象进行拷贝行为必须调用拷贝构造,所以这里传值传参要调用拷贝构造//所以这里的d1传值传参给d要调用拷贝构造完成拷贝Func1(d1); cout <<&d1 << endl;// 这里可以完成拷贝,但是不是拷贝构造,只是一个普通的构造 Date d2(&d1); d1.Print(); d2.Print();//这样写才是拷贝构造,通过同类型的对象初始化构造,而不是指针 Date d3(d1); d2.Print();// Func2返回了一个局部对象tmp的引用作为返回值// Func2函数结束,tmp对象就销毁了,相当于了一个野引用 Date ret =Func2(); ret.Print();return0;}
//以下都是调用拷贝构造 Stack st4(st3); Stack st5=st3;//由Date ret = Func2();得来
#include<iostream>usingnamespace std;typedefint STDataType;classStack{public:Stack(int n =4){ _a =(STDataType*)malloc(sizeof(STDataType)* n);if(nullptr== _a){perror("malloc申请空间失败");return;} _capacity = n; _top =0;}Stack(const Stack& st){// 需要对_a指向资源创建同样大的资源再拷贝值 _a =(STDataType*)malloc(sizeof(STDataType)* st._capacity);if(nullptr== _a){perror("malloc申请空间失败!!!");return;}memcpy(_a, st._a,sizeof(STDataType)* st._top); _top = st._top; _capacity = st._capacity;}voidPush(STDataType x){if(_top == _capacity){int newcapacity = _capacity *2; STDataType* tmp =(STDataType*)realloc(_a, newcapacity *sizeof(STDataType));if(tmp ==NULL){perror("realloc fail");return;} _a = tmp; _capacity = newcapacity;} _a[_top++]= x;}~Stack(){ cout <<"~Stack()"<< endl;free(_a); _a =nullptr; _top = _capacity =0;}private: STDataType* _a; size_t _capacity; size_t _top;};// 两个Stack实现队列classMyQueue{public:private: Stack pushst; Stack popst;};intmain(){ Stack st1; st1.Push(1); st1.Push(2);// Stack不显式实现拷贝构造,用自动生成的拷贝构造完成浅拷贝// 会导致st1和st2里面的_a指针指向同一块资源,析构时会析构两次,程序崩溃 Stack st2 = st1; MyQueue mq1;// MyQueue自动生成的拷贝构造,会自动调用Stack拷贝构造完成pushst/popst的拷贝,只要Stack拷贝构造自己实现了深拷贝,他就没问题 MyQueue mq2 = mq1;return0;}

5.赋值运算符重载

5.1 运算符重载

• 当运算符被用于类类型的对象时,C++语言允许我们通过运算符重载的形式指定新的含义。C++规定类类型对象使用运算符时,必须转换成调用对应运算符重载,若没有对应的运算符重载,则会编译报错
• 运算符重载是具有特殊名字的函数,他的名字是由operator和后面要定义的运算符共同构成。和其他函数一样,它也具有其返回类型和参数列表以及函数体
• 重载运算符函数的参数个数和该运算符作用的运算对象数量一样多。一元运算符有一个参数,二元运算符有两个参数,二元运算符的左侧运算对象传给第一个参数,右侧运算对象传给第二个参数。

• 如果一个重载运算符函数是成员函数,则它的第一个运算对象默认传给隐式的this指针,因此运算符重载作为成员函数时,参数比运算对象少一个。
• 运算符重载以后,其优先级和结合性与对应的内置类型运算符保持一致
不能通过连接语法中没有的符号来创建新的操作符:比如operator@。

在这里插入图片描述

注意以上5个运算符不能重载。(选择题里面常考,大家要记一下)

.* 符号补充演示:

voidfunc(){ cout<<"func()"<<endl;}classA{public:voidfunc2(){ cout<<"A::func()"<<endl;}};intmain(){void(*pf1)()=func1;//调用(*pf)();void(A::*pf2)()=&A::func2;//调用 A aa;(aa.*pf2)();return0;}

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

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

• 重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,无法很好的区分。C++规定,后置++重载时,增加一个int形参,跟前置++构成函数重载,方便区分。
• 重载<<和>>时,需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第一个形参位置,第一个形参位置是左侧运算对象,调用时就变成了对象<<cout,不符合使用习惯和可读性。重载为全局函数把ostream/istream放到第一个形参位置就可以了,第二个形参位置当类类型对象。

#include<iostream>usingnamespace std;// 编译报错:“operator +”必须至少有一个类类型的形参intoperator+(int x,int y){return x - y;}
#include<iostream>usingnamespace std;classDate{public:Date(int year =1,int month =1,int day =1){ _year = year; _month = month; _day = day;}voidPrint(){ cout << _year <<"-"<< _month <<"-"<< _day << endl;}//private:int _year;int _month;int _day;};booloperator==(const Date& d1,const Date& d2){return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;}intmain(){ Date d1(2024,7,5); Date d2(2024,7,6);// 运算符重载函数可以显示调用operator==(d1, d2);// 编译器会转换成 operator==(d1, d2); d1 == d2;return0;}
重载函数作用域在全局时无法访问私有成员变量

有几种方法可以解决:

1、成员放公有
这个方法得不偿失
#include<iostream>usingnamespace std;classDate{public:Date(int year =1,int month =1,int day =1){ _year = year; _month = month; _day = day;}voidPrint(){ cout << _year <<"-"<< _month <<"-"<< _day << endl;}booloperator==(const Date& d){return _year == d._year && _month == d._month && _day == d._day;} Date&operator++(){ cout <<"前置++"<< endl;//...return*this;} Date operator++(int){ Date tmp; cout <<"后置++"<< endl;//...return tmp;}private:int _year;int _month;int _day;};intmain(){ Date d1(2026,3,6); Date d2(2024,3,6);// 运算符重载函数可以显示调用 d1.operator==(d2);// 编译器会转换成 d1.operator==(d2); d1 == d2;// 编译器会转换成 d1.operator++();++d1;// 编译器会转换成 d1.operator++(0); d1++;return0;}

5.2 赋值运算符重载

赋值运算符重载是一个默认成员函数,用于完成两个已经存在的对象直接的拷贝赋值,这里要注意跟拷贝构造区分,拷贝构造用于一个对象拷贝初始化给另一个要创建的对象

赋值运算符重载的特点:

1.赋值运算符重载是一个运算符重载,规定必须重载为成员函数。赋值运算重载的参数建议写成const 当前类类型引用,否则会传值传参会有拷贝

2.有返回值,且建议写成当前类类型引用,引用返回可以提高效率,有返回值目的是为了支持连续赋值场景。

3.没有显式实现时,编译器会自动生成一个默认赋值运算符重载,默认赋值运算符重载行为跟默认拷贝构造函数类似,对内置类型成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的赋值重载函数

4.像Date这样的类成员变量全是内置类型且没有指向什么资源,编译器自动生成的赋值运算符重载就可以完成需要的拷贝,所以不需要我们显示实现赋值运算符重载。

像Stack这样的类,虽然也都是内置类型,但是_a指向了资源,编译器自动生成的赋值运算符重载完成的值拷贝/浅拷贝不符合我们的需求,所以需要我们自己实现深拷贝(对指向的资源也进行拷贝)。

像MyQueue这样的类型内部主要是自定义类型Stack成员,编译器自动生成的赋值运算符重载会调用Stack的赋值运算符重载,也不需要我们显示实现MyQueue的赋值运算符重载。

这里还有一个小技巧,如果一个类显示实现了析构并释放资源,那么他就需要显示写赋值运算符重载,否则就不需要
classDate{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;}// 传引用返回减少拷贝// d3 = d5; Date&operator=(const Date& d){// 检查自己给自己赋值的情况if(this!=&d){ _year = d._year; _month = d._month; _day = d._day;}// d3 = d5表达式的返回对象应该为d1,也就是*thisreturn*this;}voidPrint(){ cout << _year <<"-"<< _month <<"-"<< _day << endl;}private:int _year;int _month;int _day;};intmain(){ Date d1(2024,7,5); Date d2(d1); Date d3(2024,7,6); d1 = d3= d5;// 需要注意这里是拷贝构造,不是赋值重载 Date d4 = d1;return0;}

6.取地址运算符重载

6.1 const成员函数

1.将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后面。const不能修饰全局函数(可以理解为没有this指针
2.1 const修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

2.2 const 修饰Date类的Print成员函数,Print隐含的this指针由 Date* const this 变为 const Date* const this

总结:不修改成员变量的成员函数都应该加上const,这样普通对象和const对象都可以调用这个const成员函数
#include<iostream>usingnamespace std;classDate{public:Date(int year =1,int month =1,int day =1){ _year = year; _month = month; _day = day;}// void Print(const Date* const this) constvoidPrint()const{ cout << _year <<"-"<< _month <<"-"<< _day << endl;}private:int _year;int _month;int _day;};intmain(){// 这里非const对象也可以调用const成员函数是一种权限的缩小 Date d1(2024,7,5); d1.Print();const Date d2(2024,8,5); d2.Print();return0;}

6.2 取地址运算符重载

取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,一般这两个函数编译器自动生成的就可以够我们用了,不需要去显示实现。

除非一些很特殊的场景,比如我们不想让别人取到当前类对象的地址,就可以自己实现一份,胡乱返回一个地址。

classDate{public://d2调用这个 Date*operator&(){returnthis;// return nullptr;}//d1调用这个const Date*operator&()const{returnthis;// return nullptr;}private:int _year ;// 年int _month ;// 月int _day ;// 日};intmain(){const Date d1(2025,9,1);const Date* p1=&d1; Date d2(2025,9,8); Date* p2=&d2; cout<<p1<<""<<p2<<endl;return0;}

7. 日期类实现

//0+2次拷贝 Date& 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;}//反过来 1+2次拷贝 Date& Date::operator+=(int day){*this=*this+day;return*this;} Date Date::operator+(int day){if(day <0){return*this-=-day;} Date tmp(*this); tmp._day+=day;while(tmp._day>GetMonthDay(tmp._year,tmp._month)){ tmp._day-=GetMonthDay(tmp._year,tmp._month);++tmp.month;if(tmp._month==13){++tmp._year; tmp._month=1;}}return tmp;}

所以选上面那种方式

d1-d2(日期相减)

1.最简单直接办法:二者差的年数*365+跨越闰年数+(二者距自己当前年1月1号差的天数相减)

2.小的日期不断++,直到和大的日期相等,++了多少次,他们就相差多少天

总的代码演示:

//Data.h#pragmaonce#include<iostream>usingnamespace std;#include<assert.h>classDate{// 友元函数声明(也可以写在public,也可以写在private,它实质不属于这个类)// 友元函数可以访问私有变量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);voidPrint()const;// 直接定义类里面,他默认是inline// 频繁调用intGetMonthDay(int year,int month)const{assert(month >0&& month <13);//用static修饰更好staticint 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)){return29;}else{return monthDayArray[month];}}boolCheckDate();booloperator<(const Date& d)const;booloperator<=(const Date& d)const;booloperator>(const Date& d)const;booloperator>=(const Date& d)const;booloperator==(const Date& d)const;booloperator!=(const Date& d)const;// d1 += 天数 Date&operator+=(int day); Date operator+(int day)const;//不修改本身的值,可以加const// d1 -= 天数 Date&operator-=(int day); Date operator-(int day)const;// d1 - d2intoperator-(const Date& d)const;// ++d1 -> d1.operator++() Date&operator++();// d1++ -> d1.operator++(0)// 为了区分,构成重载,给后置++,强行增加了一个int形参// 这里不需要写形参名,因为接收值是多少不重要,也不需要用// 这个参数仅仅是为了跟前置++构成重载区分 Date operator++(int); Date&operator--(); Date operator--(int);//不能直接cout<<d;// 流插入//调用代码:d1.operator<<(cout);或者d1<<cout;// 不建议,因为Date* this占据了一个参数位置,使用d<<cout不符合//void operator<<(ostream& out)//{// out << _year << "/" << _month << "/" << _day << '\n';//}private:int _year;int _month;int _day;};// 重载,放成全局函数,这样就不隐含this指针 ostream&operator<<(ostream& out,const Date& d);//注意不加const istream&operator>>(istream& in, Date& d);
// Date.cpp#include"Date.h"boolDate::CheckDate(){if(_month <1|| _month >12|| _day <1|| _day >GetMonthDay(_year, _month)){returnfalse;}else{returntrue;}}Date::Date(int year,int month,int day){ _year = year; _month = month; _day = day;//检查必须在赋值之后,因为检查函数只有隐含的this指针,会访问_day等if(!CheckDate()){ cout <<"日期非法"<< endl;}}voidDate::Print()const{ cout << _year <<"-"<< _month <<"-"<< _day << endl;}//d1=d2bool Date::operator==(const Date& d)const{return _year == d._year && _month == d._month && _day == d._day;}// d1 < d2//把所有为真的情况找出来,剩下的就是假的bool Date::operator<(const Date& d)const{if(_year < d._year){returntrue;}elseif(_year == d._year){if(_month < d._month){returntrue;}elseif(_month == d._month){return _day < d._day;}}returnfalse;}// 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!(*this== d);}// d1 += 50// d1 += -50 Date& 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 -= 100 Date& Date::operator-=(int day){if(day <0){return*this+=-day;} _day -= day;//day=0也不合法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;}// 为了区分,构成重载,给后置++,强行增加了一个int形参//++d1,返回的是拷贝后,尽量用前置++ Date& 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 day =0;while(min != max){++min;++day;}return day * flag;}//第一个参数也可以写成_cout,不建议写成cout,与库里面的cout最好区分开来 ostream&operator<<(ostream& out,const Date& d){ out << d._year <<"年"<< d._month <<"月"<< d._day <<"日"<< endl;return out;//返回out可以连续输出:cout<<d1<<d2;} istream&operator>>(istream& in, Date& d){while(1){ cout <<"请依次输入年月日:>"; in >> d._year >> d._month >> d._day;if(d.CheckDate()){break;}else{ cout <<"日期非法,请重新输入:"<< endl;}}return in;}
// Test.cpp#include"Date.h"voidTestDate1(){//Date d1(2025,9,8);//d1+=100;//d1.Print();//Date d2=d1+100;//d2.Print();//d1-=50;//d1.print();//Date d3=d1-50;//d3.print();// 这里需要测试一下大的数据+和- Date d1(2025,9,8); Date d2 = d1 +2000; d1.Print(); d2.Print(); Date d3(2024,4,14); Date d4 = d3 -5000; d3.Print(); d4.Print(); Date d5(2024,4,14); d5 +=-5000; d5.Print();}voidTestDate2(){ Date d1(2025,9,8); Date d2 =++d1; d1.Print(); d2.Print(); Date d3 = d1++; d1.Print(); d3.Print(); Date d5=--d1;//d1.operator--(); d1.Print(); d5.Print(); Date d4 = d1--;//d1.operator--(10); d1.Print(); d4.Print();}voidTestDate3(){ Date d1(2026,3,4); Date d2(2026,7,15);int n = d1 - d2; cout << n << endl;}voidTestDate4(){ Date d1(2026,3,4); Date d2 = d1 +3000;// operator<<(cout, d1) cout << d1; cout << d2; cin >> d1 >> d2; cout << d1 << d2;}voidTestDate5(){const Date d1(2024,4,14); d1.Print();//d1 += 100; d1 +100; Date d2(2024,4,25); d2.Print(); d2 +=100; d1 < d2; d2 < d1;}intmain(){//TestDate1();//TestDate2();//TestDate3();TestDate4();//TestDate5();return0;}
在这里插入图片描述

Read more

你以为你在部署 AI 助手,其实也可能在打开一扇“数据侧门”:OpenClaw 安全风险全解析

你以为你在部署 AI 助手,其实也可能在打开一扇“数据侧门”:OpenClaw 安全风险全解析

🔥 个人主页:杨利杰YJlio❄️ 个人专栏:《Sysinternals实战教程》《Windows PowerShell 实战》《WINDOWS教程》《IOS教程》《微信助手》《锤子助手》《Python》《Kali Linux》《那些年未解决的Windows疑难杂症》🌟 让复杂的事情更简单,让重复的工作自动化 你以为你在部署 AI 助手,其实也可能在打开一扇“数据侧门”:OpenClaw 安全风险全解析 * * 1、你以为你在装 AI 助手,其实你可能在给系统加一个“高权限自动化入口” * 2、OpenClaw 和普通 AI 最大的区别,到底在哪里? * 3、我为什么说:OpenClaw 更像“拿到部分权限的数字操作员”? * 4、为什么说 AI 助手不是“更聪明的搜索框”? * 5、OpenClaw 的 5

By Ne0inhk
人工智能:注意力机制与Transformer模型实战

人工智能:注意力机制与Transformer模型实战

人工智能:注意力机制与Transformer模型实战 1.1 本章学习目标与重点 💡 学习目标:掌握注意力机制的核心原理、经典注意力算法,以及Transformer模型的架构设计与实战应用。 💡 学习重点:理解自注意力与多头注意力的计算逻辑,学会使用TensorFlow搭建Transformer模型,完成机器翻译任务。 1.2 注意力机制的核心思想 1.2.1 为什么需要注意力机制 💡 传统的RNN和LSTM在处理长序列时,存在长距离依赖捕捉能力不足和并行计算效率低的问题。注意力机制的出现,解决了这两个核心痛点。 注意力机制的本质是让模型学会“聚焦”——在处理序列数据时,自动分配不同的权重给输入序列中的各个元素,重点关注与当前任务相关的信息,弱化无关信息的干扰。 比如在机器翻译任务中,翻译“我爱中国”时,模型会给“我”“爱”“中国”分配不同的注意力权重,从而更精准地生成对应的英文翻译。 1.2.2 注意力机制的基本框架 💡 注意力机制的计算通常包含**查询(Query)、键(Key)、值(

By Ne0inhk
酒馆玩家们,别再为API抓耳挠腮了:这16元够你玩半年,还送你全套DeepSeek

酒馆玩家们,别再为API抓耳挠腮了:这16元够你玩半年,还送你全套DeepSeek

欢迎来到小灰灰的博客空间!Weclome you! 博客主页:IT·小灰灰 爱发电:小灰灰的爱发电 热爱领域:前端(HTML)、后端(PHP)、人工智能、云服务 目录 一、16元,在AI时代是什么概念? 二、为什么是硅基流动?——酒馆玩家的隐形最优解 1. 原生DeepSeek,无需海外支付 2. 实测TTFT(首Token延迟) 3. 生态集成度 三、手把手:从0到1,把酒馆支棱起来(附极简配置) 四、这16元,还可以怎么花? 4.1 批量生成角色卡预设 4.2 模型对比测试(A/B Test) 五、邀请机制:我拿16元,

By Ne0inhk
OpenAI发布GPT-5.3 Instant:幻觉率最高降低26.8%,2026全球AI模型排行榜

OpenAI发布GPT-5.3 Instant:幻觉率最高降低26.8%,2026全球AI模型排行榜

🔥 个人主页:杨利杰YJlio❄️ 个人专栏:《Sysinternals实战教程》《Windows PowerShell 实战》《WINDOWS教程》《IOS教程》《微信助手》《锤子助手》《Python》《Kali Linux》《那些年未解决的Windows疑难杂症》🌟 让复杂的事情更简单,让重复的工作自动化 OpenAI发布GPT-5.3 Instant:幻觉率最高降低26.8%,2026全球AI模型排行榜 * 1 GPT-5.3 Instant 发布 * 2 本次升级三大核心能力 * 2.1 降低 AI 幻觉 * 2.2 减少不必要拒答 * 2.3 网络搜索能力升级 * 3 GPT-5.3 Instant 技术架构 * 4 GPT-5.3 vs

By Ne0inhk