172210704111-陈国佳总结《12月4日》【连续055天】
标题:赋值运算符的重载和运算符重载为友元函数,例题算24(递归)学习;
内容:A.赋值运算符的重载:
054day提到了重载限制:'=''只能重载为成员函数;
1)示例:定义一个字符串类(String)(这里只是示例,我们默认string未被声明),通过重载‘=’来使得char*类型的字符串可以赋值给一个字符串对象;
class String{
private :
char*str;
public :
String ():str(new char[1]){ str[0]=0;}
const char*c_str() { return str;}
String & operator =(const char *s);
~String(){delete [] str;}
};
String & String::operator =(const char *s)
{
delete [] str;
str =new char [strlen(s)+1];
strcpy(str,s);
return *this;
}
int main()
{
String s;
s="Good Luck"; //等价于s.operator=("Good Luck");
cout<<s.c_str()<<endl;
s="Hello"; //String s2="Hello"出错,因为这里用的是初始化函数,而不是赋值;
cout<<s.c_str()<<endl;
return 0;
}
输出:Good Luck
Hello
2)浅拷贝和深拷贝:
上述的程序中,如果我们写:
String S1,S2;
S1="this";
S2="that";
S1=S2;
由于这是两个String类型的对象,=会是它的原义,但由于‘=’的意思是S1的字节完全等于S2,
而String对象里的成员str是指针,所以S1会指向S2的动态内存空间,就会产生BUG;
因此可加:
String & String::operator =(const String & s)
{
delete [] str;
str =new char [strlen(s.str)+1];
strcpy(str,s.str);
return *this;
}
如果有人写 String s; s="Hello";s=s;
又会产生BUG(先delete),所以还要加一个判断:
if(this ==&s) return *this ;
3)上式对‘=’的重载其返回值是String &:
为什么?这个是为了保持运算符的原有特性;
a=b=c; //a和b的值都是c的值 //a.operator=(b.operator=(c));
(a=b)=c;//会修改a的值; //(a.operator=(b)).operator=(c);
如果重载返回值是void或String 都无法如原“=”一样;
4)上式程序还存在一个问题:
复制构造函数会存在2)的问题;
所以要加:
String (String & s)
{ str =new char[strlen(s.str)+1];
strcpy(str,s.str)}
B.运算符重载为友元函数:
class Complex{
double real,imag;
public:
Complex(double r=0.0,double i=0.0):real(r),imag(i){}
Complex operator+(double r);
};
Complex Complex::operator+(double r)
{
return Complex(real+r,imag);
}
c=c+5 //通过;
c=5+c //出错;
我们需要将函数改为普通函数,但为了访问Complex的私有成员,
需要将其改为友元函数:
class Complex{...........public: friend ... +....};
C.算24:
给出4个小于10的正整数,通过加减乘除4种运算以及括号,问是否可以得到24(除法定义为实数除法,运算优先级与平时一致)
输入:多组数据,每行一组,4个0表示结束;
输出:对每组数据输出YES和NO;
思路:n个数求24,先取2个数,运算后,得到运算结果,就变成了n-1个数求24;
边界条件:
只剩一个数,判断是否等于24(浮点数比较不能用“==”)
例:
double a[5];
#define EPS 1e-6
bool isZero(double x){
return fabs(x) <=EPS;
}
bool count24(double a[],int n)
{
if(n==1){
if(isZero(a[0]-24))
return true;
else
return false;
}
double b[5]; //储存剩下的n-2个数和计算结果
for(int i=0;i<n-1;++i)
for(int j=i+1;j<n;++j){
int m=0;
for(int k=0;k<n;++k)
if(k!=i && k!=j)
b[m++]=a[k];
b[m]=a[i]+a[j];
if(count24(b,m+1))
return true;
b[m]=a[i]-a[j];
if(count24(b,m+1))
return true;
b[m]=a[j]-a[i];
if(count24(b,m+1))
return true;
b[m]=a[i]*a[j];
if(count24(b,m+1))
return true;
if(!isZero(a[j])){
b[m]=a[i]/a[j];
if(count24(b,m+1))
return true;
}
if(!isZero(a[i])){
b[m]=a[j]/a[i];
if(count24(b,m+1))
return true;
}
}return false;
}
int main()
{
while(true){
for(int i=0;i<4;++i)
cin>>a[i];
if(isZero(a[0]))break;
if(count24(a,4))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
明日计划:可变长数组类的实现;