还是有问题,大家在帮忙看看,重载作业

minijazz 2003-06-01 05:12:12
//Complex.h
class Complex
{
public:
Complex();
Complex(float n1,float n2);
Complex operator+ (const Complex &S)const;
Complex operator- (const Complex &S)const;
Complex operator* (float n)const;
Complex operator~ ();
friend Complex operator * (float n,const Complex &S2);
friend Complex operator * (const Complex &S1,const Complex &S2);
friend Complex operator / (const Complex &S1,const Complex &S2);
friend istream & operator > > (istream & is,const Complex & S);
friend ostream & operator < < (ostream & os,const Complex & S);
private:
float real;
float imaginary;
};
//Complex.cpp
#include <iostream >
#include <cmath >
using namespace std;
#include "Complex.h "

Complex::Complex()
{real=imaginary=0.0;}

Complex::Complex(float n1,float n2)
{real=n1;
imaginary=n2;
}

Complex Complex::operator +(const Complex &S)const
{return Complex(real+S.real,imaginary+S.imaginary);
}

Complex Complex::operator -(const Complex &S)const
{return Complex(real-S.real,imaginary-S.imaginary);
}

Complex Complex::operator *(float n)const
{return Complex(real*n,imaginary*n);
}

Complex Complex::operator~ ()
{
return Complex(real,-imaginary);
}

//friend
Complex operator *(float n,Complex &S)
{
return S*n;
}

Complex operator *(const Complex &S1,const Complex &S2)
{
float n1=S1.real*S2.real-S1.imaginary*S2.imaginary;
float n2=S1.real*S2.imaginary+S1.imaginary*S2.real;
Complex result(n1,n2);

return result;
}

Complex operator /(const Complex &S1,const Complex &S2)
{float n1=(S1.real*S2.real+S1.imaginary*S2.imaginary)/(S2.real*S2.real+S2.imaginary*S2.imaginary);
float n2=(-S1.real*S2.imaginary+S1.imaginary*S2.real)/(S2.real*S2.real+S2.imaginary*S2.imaginary);
Complex result(n1,n2);
return result;
}

istream & operator > > (istream & is, const Complex & S)
{
cout < < "real: ";
is > >S.real;
cout < <endl;
cout < < "imaginary: ";
is > >S.imaginary;
cout < <endl;
return is;
}

ostream & operator < < (ostream & os,const Complex & S)
{
os < < "( " < <S.real < < " , " < <S.imaginary < < "i " < < " ) " ;
return os;
}

//user.cpp
#include <iostream >
using namespace std;
#include "Complex.h "
int main()
{
Complex a(3.0,4.0);
Complex c;
cout < < "Enter a complex number(q to quit):\n ";
while(cin > >c)
{
cout < < " c is " < < c < <endl;
cout < < "complex conjugate is " < < ~c < <endl;
cout < < "a is " < < a < < endl;
cout < < "a+c is " < < a+c < < endl;
cout < < "a-c is " < < a-c < < endl;
cout < < "a*c is " < < a*c < < endl;
cout < < "a*2 is " < < a*2 < < endl;
cout < < "2*c is " < < 2*c < < endl;
cout < < "a/c is " < < a/c < < endl;
cout < < "Enter a complex number(q to quit):\n ";
}
cout < < "Done!\n ";
return 0;
}

怎么还是在重载〈〈和〉〉中有问题啊?
...全文
22 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
Peterwby 2003-06-12
  • 打赏
  • 举报
回复
我问一下ho,前面不是说
istream & operator >> (istream & is, Complex & S)
{
cout<<"real: ";
is>>S.real;
cout<<endl;
cout<<"imaginary: ";
is>>S.imaginary;
cout<<endl;
return is;
}
“里面的is>>S.real语句,你知道这时候的operator>>是用的哪个重载么?
这时候用的operator>>是在iostream文件里面为你重载的,它没有定义为你的friend,所以你现在无论怎么改还是会出现“不能使用私有成员”的错误,除非你把real改称公有成员变量” ,为什么只要在文件开头加几个声明,就可以访问私有成员S.real了呀
yin0731 2003-06-12
  • 打赏
  • 举报
回复
wait!
程序好长啊!
我一定要学学!呵呵!
有肯教我的发帖子给我把吧!
我还有一大堆程序有问题呢
qrlvls 2003-06-12
  • 打赏
  • 举报
回复
">>" "<<"
Not
"> >" "< <"
Mr月亮 2003-06-12
  • 打赏
  • 举报
回复
To Peterwby(wuhen) :
看清楚我写的
“它的函数体内所调用到的外部函数f2也可以使用类A的私有成员作为参数”
是做为参数,没说外部函数的函数体内也可以用类的私有成员呀
minijazz 2003-06-12
  • 打赏
  • 举报
回复
我发现上次的程序能够通过了,只是在定义Complex operator *(float n,Complex &S)掉了const
与申明不一致,从而会有两个连接错误。

我已经准备将此贴结题了,在这感谢各位的鼎力相助,特别鸣谢xmagicwu(死过方生) 兄。
晚上来放分
Peterwby 2003-06-12
  • 打赏
  • 举报
回复
是不是这个意思,好象不行阿,g()里面的a.a = 1;还是会出错?

#include <iostream>
using namespace std;

class A {
int a;
public:
friend void f(A& a);

};

void g(A& a)
{
a.a = 1;
}

void f(A& a)
{
a.a = 2;
g(a);
}

int main()
{

}
Mr月亮 2003-06-12
  • 打赏
  • 举报
回复
To Peterwby(wuhen) :
你点到了问题的症结所在!
第一:我上面的说法有一定的问题存在,验证过后证明只要函数f1被声明成为类A的friend不但它自己可以使用类A的私有成员,而且它的函数体内所调用到的外部函数f2也可以使用类A的私有成员作为参数(注:要使这种情况成立则调用函数f2并给它传递类A的私有成员为参数的语句必须写在友元函数f1体内的)。

第二:你可以做个实验--
如果函数名不是operator >>或者其他运算符,而是普通名称的话这段语句是可以run的。这时候我们就撞上了VC的bug了,加那几个声明只是为了避开这个bug而已。
Mr月亮 2003-06-11
  • 打赏
  • 举报
回复
To lijdking(exploit) :
你的程序改成这样也可以运行无误

#include<iostream>
using namespace std;
/**********************************************************************/
//我增加的语句
class A;
ostream &operator <<(ostream &,const A&);
istream &operator >>(istream &,A&);
void f(A&);
/**********************************************************************/


class A
{
friend ostream &operator <<(ostream &,const A&);
friend istream &operator >>(istream &,A&);
friend void f(A&);
int real;
int *p;
int size;
public:
A(){real=0;size=3;p=new int[size];}


};
ostream &operator <<(ostream &os,const A&obj)
{
os<<obj.real<<endl;
cout<<"test"<<endl;
os<<"ni hao"<<endl;
return os;
}
istream &operator >>(istream & is,A &obj)
{
cout<<"输入real的值:";
is>>obj.real; //也可以操作
cout<<endl;
cout<<"输出real的值是:"<<obj.real<<endl;


for(int i=0;i<obj.size;i++)
{
cout<<"对数组复制 :";
is>>obj.p[i]; //可以啊!
cout<<endl;
}
return is;
}
void f(A & obj)
{
cout<<"real的值是:"<<obj.real<<endl;

for(int i=0;i<obj.size;i++)
{cout<<"数组的值是:"<<obj.p[i]<<endl;}
}
void main()
{
A b;
cout<<b<<endl;
cin>>b;
f(b);
}

呵呵,通过这两天的讨论和对你们的例程的调试我发现VC在处理标准C++里面--重载为友元函数的运算符操作类的私有成员,这个问题上面存在重大bug,我下载了SP5还是不可以解决。一定要进行class和friend function的提前声明才可以解决。
Peterwby 2003-06-11
  • 打赏
  • 举报
回复
up
Mr月亮 2003-06-11
  • 打赏
  • 举报
回复
To minijazz(换名中……) :
我把你的3个文件合并成一个,稍微加了一点编译通过,运行无误

//Complex.h
#include <iostream>
#include <cmath>

using namespace std;

/*****************************************************************/
//我增加的语句
class Complex;
Complex operator * (float n,const Complex &S2);
Complex operator * (const Complex &S1,const Complex &S2);
Complex operator / (const Complex &S1,const Complex &S2);
istream & operator >> (istream & is,Complex & S);
ostream & operator << (ostream & os,const Complex & S);
/*****************************************************************/


class Complex
{
public:
Complex();
Complex(float n1,float n2);
Complex operator+ (const Complex &S)const;
Complex operator- (const Complex &S)const;
Complex operator* (float n)const;
Complex operator~ ();

friend Complex operator * (float n,const Complex &S2);
friend Complex operator * (const Complex &S1,const Complex &S2);
friend Complex operator / (const Complex &S1,const Complex &S2);

friend istream & operator >> (istream & is,Complex & S);
friend ostream & operator << (ostream & os,const Complex & S);
private:
float real;
float imaginary;
};
//istream & operator >> (istream & is,Complex & S);


//Complex.cpp
Complex::Complex()
{real=imaginary=0.0;}

Complex::Complex(float n1,float n2)
{real=n1;
imaginary=n2;
}

Complex Complex::operator +(const Complex &S)const
{return Complex(real+S.real,imaginary+S.imaginary);
}

Complex Complex::operator -(const Complex &S)const
{return Complex(real-S.real,imaginary-S.imaginary);
}

Complex Complex::operator *(float n)const
{return Complex(real*n,imaginary*n);
}

Complex Complex::operator~ ()
{
return Complex(real,-imaginary);
}

//friend
Complex operator *(float n,Complex &S)
{
return S*n;
}

Complex operator *(const Complex &S1,const Complex &S2)
{
float n1=S1.real*S2.real-S1.imaginary*S2.imaginary;
float n2=S1.real*S2.imaginary+S1.imaginary*S2.real;
Complex result(n1,n2);

return result;
}

Complex operator /(const Complex &S1,const Complex &S2)
{float n1=(S1.real*S2.real+S1.imaginary*S2.imaginary)/(S2.real*S2.real+S2.imaginary*S2.imaginary);
float n2=(-S1.real*S2.imaginary+S1.imaginary*S2.real)/(S2.real*S2.real+S2.imaginary*S2.imaginary);
Complex result(n1,n2);
return result;
}

istream & operator >> (istream & is, Complex & S)
{
cout<<"real: ";
is>>S.real;
cout<<endl;
cout<<"imaginary: ";
is>>S.imaginary;
cout<<endl;
return is;
}

ostream & operator << (ostream & os,const Complex & S)
{
os <<"( "<<S.real<<" ,"<<S.imaginary<<"i"<<" )" ;
return os;
}

//user.cpp
int main()
{
Complex a(3.0,4.0);
Complex c;
cout<<"Enter a complex number(q to quit):\n";
while(cin>>c)
{
cout <<" c is "<< c<<endl;
cout <<"complex conjugate is"<< ~c<<endl;
cout <<"a is"<< a<< endl;
cout <<"a+c is"<< a+c<< endl;
cout <<"a-c is"<< a-c<< endl;
cout <<"a*c is"<< a*c<< endl;
cout <<"a*2 is"<< a*2<< endl;
cout <<"2*c is"<< 2*c<< endl;
cout <<"a/c is"<< a/c<< endl;
cout <<"Enter a complex number(q to quit):\n";
}
cout <<"Done!\n";
return 0;
}
minijazz 2003-06-11
  • 打赏
  • 举报
回复
我按xmagicwu(死过方生)兄所说的,试过仍然有以下两个错误
Linking...
user.obj : error LNK2001: unresolved external symbol "class Complex __cdecl operator*(float,class Complex const &)" (??D@YA?AVComplex@@MABV0@@Z)Debug/MyComplex.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
MyComplex.exe - 2 error(s), 0 warning(s)

cat0928 2003-06-10
  • 打赏
  • 举报
回复
友元不可以访问私有成员?
Mr月亮 2003-06-10
  • 打赏
  • 举报
回复
to lijdking(exploit) :
你所用的库和我们所说的前提不一样,我们用的是标准化c++库iostream而你用的是标准化以前的库iostream.h,你说的这个例子也恰恰反映了iostream.h相对于iostream来说是不安全的。不信你可以试一试把#include<iostream.h>改成#include<iostream>然后在下面加上一条这个语句using namespace std;你编译,马上就可以看见“不能使用私有成员”的错误信息。

ptr是类私有成员,而ptr[i]则与这个类没有任何关系,是一个外部数据,所以可以被访问。

to minijazz(换名中……) :
如果你实在不想改动太大的话就只好牺牲一点安全性,将就着用iostream.h库文件咯,然后去掉名字空间。
minijazz 2003-06-10
  • 打赏
  • 举报
回复
共同学习
lijdking 2003-06-10
  • 打赏
  • 举报
回复
其实觉得xmagicwu(死过方生)

这里ptr是私有成员,但是有没有说ptr[i]是私有的呀?
说得很有理,但不知道为什么还能访问?
楼主不会介意我在这里问吧?
共同学习
lijdking 2003-06-10
  • 打赏
  • 举报
回复
对xmagicwu(死过方生) 提出疑问:
朋友看好咯:
private:
float real;
这里real是私有成员
is>>S.real;里面操作的是real //你不是说这里不行?

private:
int size; //数组长度
int* ptr; //数组首地址
这里ptr是私有成员,但是有没有说ptr[i]是私有的呀?看清楚咯,hehe
is >> myarray.ptr[i];里面操作的可是ptr[i]哟 //你上一个回帖不是说可以?

我特意写了一个程序,比较乱些,只是为了验证
#include<iostream.h>
class A
{
friend ostream &operator <<(ostream &,const A&);
friend istream &operator >>(istream &,A&);
friend void f(A&);
int real;
int *p;
int size;
public:
A(){real=0;size=3;p=new int[size];}


};
ostream &operator <<(ostream &os,const A&obj)
{
os<<obj.real<<endl;
cout<<"test"<<endl;
os<<"ni hao"<<endl;
return os;
}
istream &operator >>(istream & is,A &obj)
{
cout<<"输入real的值:";
is>>obj.real; //也可以操作
cout<<endl;
cout<<"输出real的值是:"<<obj.real<<endl;


for(int i=0;i<obj.size;i++)
{
cout<<"对数组复制 :";
is>>obj.p[i]; //可以啊!
cout<<endl;
}
return is;
}
void f(A & obj)
{
cout<<"real的值是:"<<obj.real<<endl;

for(int i=0;i<obj.size;i++)
{cout<<"数组的值是:"<<obj.p[i]<<endl;}
}
void main()
{
A b;
cout<<b<<endl;
cin>>b;
f(b);
}
以上均可以编译通过运行
本人还是初学者请多多指教
minijazz 2003-06-10
  • 打赏
  • 举报
回复
很感谢xmagicwu(死过方生) 的朋友诲人不倦
那么如果只能改掉私有成员,似乎不是太妥哟
有没有更好的方法把此类修理一下啊?
各位,请给点意见!谢了
Mr月亮 2003-06-10
  • 打赏
  • 举报
回复
朋友看好咯:
private:
float real;
这里real是私有成员
is>>S.real;里面操作的是real

private:
int size; //数组长度
int* ptr; //数组首地址
这里ptr是私有成员,但是有没有说ptr[i]是私有的呀?看清楚咯,hehe
is >> myarray.ptr[i];里面操作的可是ptr[i]哟
lijdking 2003-06-10
  • 打赏
  • 举报
回复
istream & operator >> (istream & is, Complex & S)
{
cout<<"real: ";
is>>S.real; //1:
cout<<endl;
cout<<"imaginary: ";
is>>S.imaginary;
cout<<endl;
return is;
}

istream& operator >>(istream& is,Array& myarray)
{
for (int i=0;i<myarray.size;i++)
{
is >> myarray.ptr[i]; //2:
}
return is;
}

实在看不出1与2有什么区别?操作符>>都声明了friend了?输入的都是对象的私有成员?
为什么2可以而1却不可以?
对xmagicwu(死过方生)老兄说的还是不明白啊
急需高手再指点一下!谢谢!

Mr月亮 2003-06-09
  • 打赏
  • 举报
回复
朋友你在
istream & operator >> (istream & is, Complex & S)
{
cout<<"real: ";
is>>S.real;
cout<<endl;
cout<<"imaginary: ";
is>>S.imaginary;
cout<<endl;
return is;
}
里面的is>>S.real语句,你知道这时候的operator>>是用的哪个重载么?
这时候用的operator>>是在iostream文件里面为你重载的,它没有定义为你的friend,所以你
现在无论怎么改还是会出现“不能使用私有成员”的错误,除非你把real改称公有成员变量

兄弟,你痛苦了你,hehe
加载更多回复(14)

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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