(求助)关于重载输出运算符“<<”及与拷贝构造函数的冲突(详见代码)

苏菲落红 2018-05-24 09:16:13
Description

设计一个简单的SmallInt类,用来表示从-128到127之间的整数。类的唯一的数据成员val存放一个-128到127(包含-128和127这两个数)之间的整数。根据给定的main函数设计必要的成员函数。main函数已给定,提交时只需要提交main函数外的代码部分。
【注意】构造SmallInt类对象时,当给定整数不在指定范围时,需要做相应正规化处理。所谓正规化处理就是当成员数据val的值大于127时,就要减去256,当val的值小于-128时,就需要加上256,直到满足要求为止。

Input

包含多组数据(数据均正确合法) 每组输入数据一行,包含2个整数。

Output

对于每组测试数据的输出结果见Sample Output。

Sample Input


1 2 128 -128 256 128

Sample Output

Case 1:
s1=1
s2=2
s1+s2=3
s1-s2=-1
s1s2=2
s1/s2=0
Case 2:
s1=-128
s2=-128
s1+s2=0
s1-s2=0
s1s2=0
s1/s2=1
Case 3:
s1=0
s2=-128
s1+s2=-128
s1-s2=-128
s1*s2=0
s1/s2=0


#include<iostream>
using namespace std;

class SmallInt
{
int val;
public:
SmallInt(){val=0;}
SmallInt(int n){while(n<-128)n+=256;while(n>127)n-=256;val=n;}
SmallInt(SmallInt &s){val=s.val;}
~SmallInt(){}
void Set(int n){while(n<-128)n+=256;while(n>127)n-=256;val=n;}
SmallInt operator+(SmallInt &s);
SmallInt operator-(SmallInt &s);
SmallInt operator*(SmallInt &s);
SmallInt operator/(SmallInt &s);
int GetInt(){return val;}
};

SmallInt SmallInt::operator+(SmallInt &s)//重载‘+’
{
SmallInt s1;
s1.val=val+s.val;
while(s1.val<-128)s1.val+=256;
while(s1.val>127)s1.val-=256;
return s1;
}

SmallInt SmallInt::operator-(SmallInt &s)//重载‘-’
{
SmallInt s1;
s1.val=val-s.val;
while(s1.val<-128)s1.val+=256;
while(s1.val>127)s1.val-=256;
return s1;
}

SmallInt SmallInt::operator*(SmallInt &s)//重载‘*’
{
SmallInt s1;
s1.val=val*s.val;
while(s1.val<-128)s1.val+=256;
while(s1.val>127)s1.val-=256;
return s1;
}

SmallInt SmallInt::operator/(SmallInt &s)//重载‘/’
{
SmallInt s1;
s1.val=val/s.val;
while(s1.val<-128)s1.val+=256;
while(s1.val>127)s1.val-=256;
return s1;
}

istream& operator>>(istream &i,SmallInt &s)//重载输入
{
int n;
i>>n;
s.Set(n);
return i;
}

ostream& operator<<(ostream &o,SmallInt &s)//重载输出,devc++报错 ,但在删去自己写的拷贝构造函数并去掉s的引用后程序通过
{
o<<s.GetInt();
return o;
}

int main()
{
int cas=0;
SmallInt s1,s2;
while(cin>>s1>>s2)
{
cas++;
cout<<"Case "<<cas<<":"<<endl;
cout<<"s1="<<s1<<endl;
cout<<"s2="<<s2<<endl;
cout<<"s1+s2="<<s1+s2<<endl;
cout<<"s1-s2="<<s1-s2<<endl;
cout<<"s1*s2="<<s1*s2<<endl;
cout<<"s1/s2="<<s1/s2<<endl;
}
return 0;
}
...全文
809 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
苏菲落红 2018-05-27
  • 打赏
  • 举报
回复
今天又有一个新的问题,也是输出运算符重载,作为友元函数的。

	friend ostream& operator<<(ostream &o,Grid &g)//友元函数,按照指定格式(见Sample Output)显示对象g的信息
	{
		o<<'['<<g.GetLetter()<<','<<g.GetNumber()<<']';
		return o;
	}
上述代码,若放在类中先声明,再在类外定义的话,就会被vc6.0报错error C2593: 'operator <<' is ambiguous。 但是!但是!dev中过了! 然而,如果就在类内写定义的话,vc可以过。 具体题目和代码见下图,最令我困惑的是用了三次‘<<’,可结果竟然是后两个报错,第一个怎么过的??? Description 某工程包含Letter类、Number类和Grid类。其中Grid类由Letter类和Number类公有派生。 (1)Letter类包含一个私有成员数据ch(类型为char) 各成员函数原型声明如下: Letter(char c);//构造函数,用来初始化ch,默认值为字符A,并输出信息"Class Letter is constructed" char GetLetter();//用来返回ch的值,并输出信息"Class Letter is get" void SetLetter(char c);//用来设置修改ch的值,并输出信息"Class Letter is reset" (2)Number类包含一个私有成员数据num(类型为int) 各成员函数原型声明如下: Number(int n);//构造函数,用来初始化num,默认值为0,并输出信息"Class Number is constructed" int GetNumber();//用来返回num的值,并输出信息"Class Number is get" void SetNumber(int n);//用来设置修改num的值,并输出信息"Class Number is reset" (3)Grid类没有增加新的成员数据,包含两个构造函数(一个不带参数,一个带参数),成员函数Set(带2个参数)用来改变成员数据的值。 Grid();//构造函数,并输出信息"Class Grid is constructed default" Grid(char c,int n);//构造函数,参数分别用来初始化基类Letter和Number,并输出信息"Class Grid is constructed" void Set(char c,int n);//设置修改基类的各成员数据的值,并输出信息"Class Grid is reset" friend ostream& operator<<(ostream &o,Grid &g);//友元函数,按照指定格式(见Sample Output)显示对象g的信息 (4)设计上述类,并采用下面的main函数进行测试(提交时只需提交除main函数外的代码部分) int main() { int n; char ch; Grid g1; cout<<"Default Grid reference:"<<g1<<endl; cin>>n>>ch; Grid g2(ch,n); cout<<"Grid reference:"<<g2<<endl; cin>>n>>ch; g2.Set(ch,n); cout<<"Grid reference:"<<g2<<endl; return 0; } Sample Input 12345 T 2587145 W Sample Output Class Letter is constructed Class Number is constructed Class Grid is constructed default Default Grid reference:[A,0] Class Letter is constructed Class Number is constructed Class Grid is constructed Grid reference:[T,12345] Class Letter is reset Class Number is reset Class Grid is reset Grid reference:[W,2587145] 代码:

#include<iostream>
using namespace std;

class Letter
{
	char ch;
public:
	Letter(char c);//构造函数,用来初始化ch,默认值为字符A,并输出信息"Class Letter is constructed"
    char GetLetter();//用来返回ch的值,并输出信息"Class Letter is get"
    void SetLetter(char c);//用来设置修改ch的值,并输出信息"Class Letter is reset"
};

Letter::Letter(char c)//构造函数,用来初始化ch,默认值为字符A,并输出信息"Class Letter is constructed"
{
	ch=c;
	cout<<"Class Letter is constructed"<<endl;
}

char Letter::GetLetter()//用来返回ch的值,并输出信息"Class Letter is get"
{

	return ch;	cout<<"Class Letter is get"<<endl;
}

void Letter::SetLetter(char c)//用来设置修改ch的值,并输出信息"Class Letter is reset"
{
	ch=c;
	cout<<"Class Letter is reset"<<endl;
}


class Number
{
	int num;
public:
    Number(int n);//构造函数,用来初始化num,默认值为0,并输出信息"Class Number is constructed"
    int GetNumber();//用来返回num的值,并输出信息"Class Number is get"
    void SetNumber(int n);//用来设置修改num的值,并输出信息"Class Number is reset"
};

Number::Number(int n)//构造函数,用来初始化num,默认值为0,并输出信息"Class Number is constructed"
{
	num=n;
	cout<<"Class Number is constructed"<<endl;
}

int Number::GetNumber()//用来返回num的值,并输出信息"Class Number is get"
{
	
	return num;cout<<"Class Number is get"<<endl;
}

void Number::SetNumber(int n)//用来设置修改num的值,并输出信息"Class Number is reset"
{
	num=n;
	cout<<"Class Number is reset"<<endl;
}


class Grid:public Letter,public Number
{
public:
	Grid():Letter('A'),Number(0){cout<<"Class Grid is constructed default"<<endl;}//构造函数,并输出信息"Class Grid is constructed default"
    Grid(char c,int n):Letter(c),Number(n){cout<<"Class Grid is constructed"<<endl;}//构造函数,参数分别用来初始化基类Letter和Number,并输出信息"Class Grid is constructed"
    void Set(char c,int n);//设置修改基类的各成员数据的值,并输出信息"Class Grid is reset"
	friend ostream& operator<<(ostream &o,Grid &g);//友元函数,按照指定格式(见Sample Output)显示对象g的信息
};

void Grid::Set(char c,int n)//设置修改基类的各成员数据的值,并输出信息"Class Grid is reset"
{
	SetLetter(c);
	SetNumber(n);
	cout<<"Class Grid is reset"<<endl;
}

 ostream& operator<<(ostream &o,Grid &g)//友元函数,按照指定格式(见Sample Output)显示对象g的信息
	{
		o<<'['<<g.GetLetter()<<','<<g.GetNumber()<<']';
		return o;
	}//呐,就是这里!



int main()
{
    int n;
    char ch;
    Grid g1;
    cout<<"Default Grid reference:"<<g1<<endl;
    cin>>n>>ch;
    Grid g2(ch,n);
    cout<<"Grid reference:"<<g2<<endl;
    cin>>n>>ch;
    g2.Set(ch,n);
    cout<<"Grid reference:"<<g2<<endl;
    return 0;
}
vc让我很困惑,有兴趣的大佬可以研究一下。 对于这些代码放在类里还是放在类外面着实困惑呢。两个问题似乎都有些相同吧??
  • 打赏
  • 举报
回复
编译没错啊,code原封不动用visual studio express编译通过: ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 然后是输入输出,看起来和你给出的一样: 1 2 128 -128 256 128 Case 1: s1=1 s2=2 s1+s2=3 s1-s2=-1 s1*s2=2 s1/s2=0 Case 2: s1=-128 s2=-128 s1+s2=0 s1-s2=0 s1*s2=0 s1/s2=1 Case 3: s1=0 s2=-128 s1+s2=-128 s1-s2=-128 s1*s2=0 s1/s2=0
百合杰 2018-05-24
  • 打赏
  • 举报
回复
ostream& operator<<(ostream &o,SmallInt &s)//重载输出,devc++报错 ,但在删去自己写的拷贝构造函数并去掉s的引用后程序通过 
{
    o<<s.GetInt();
    return o;
}
把这一段写到类SmallInt外面
jianminfly 2018-05-24
  • 打赏
  • 举报
回复
1 2 Case 1: s1=1 s2=2 s1+s2=3 s1-s2=-1 s1*s2=2 s1/s2=0 12 21 Case 2: s1=12 s2=21 s1+s2=33 s1-s2=-9 s1*s2=-4 s1/s2=0 1 2
赵4老师 2018-05-24
  • 打赏
  • 举报
回复
《C++编程思想》

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧