注册 登录
编程论坛 C++教室

[讨论]友元与标准名空间矛盾问题

weishj 发布于 2007-05-05 23:19, 900 次点击

VC++6.0中存在使用了标准名空间后友元函数不能访问类私有成员的问题,但恰恰有些东西不使用标准名空间会出现问题,如果即要使用友元函数,又想使用比如string类的内容,就会出现一系列问题,下面举个例子,其代码来自解一元二次方程那个帖子,我重载了>>操作符只是为了说明这个问题,并没什么实际使用价值,其测试部分也没写
/************若这样,则编译时无法使用string类************************/
#include <iostream.h>
#include <math.h>
#include <string.h>
//using namespace std;
/*******************************************************************/
/**********************若按下面,则友元函数无法访问私有成员**********/
/*
#include <iostream>
#include <math.h>
#include <string>
using namespace std;
*/
class funtion
{
public:
~funtion(){cout<<"求解完毕"<<endl;}
void set_value(); //输入函数
void display(); //求解函数
void show_value();//输出函数
friend istream& operator >>(istream& ins,funtion& f);
private:
float a;
float b;
float c;
float x1;
float x2;
float r;
float i;
float pd;
};
istream& operator >>(istream& ins,funtion& f)
{
string str[3];
//ax^2+bx+c=0
IfError:
ins>>f.a>>str[0]>>f.b>>str[1]>>f.c>>str[2];
if(0==a || "x^2+"!=str[0] || "x+"!=str[1] || "=0"!=str[2])
{
cerr<<"输入错误,请输入方程(ax^2+bx+c=0)"<<endl;
ins.ignore();
ins.clear();
goto IfError;
}
return ins;
}
void funtion::set_value ()
{
cout<<"输入 a b c 的值且 a b c 不可全为零"<<endl;
cin>>a;
cin>>b;
cin>>c;
}
void funtion::display ()
{
pd=b*b-4*a*c;
if(pd>0)
{
x1=-b/(2*a)+sqrt(pd)/(2*a);
x2=-b/(2*a)-sqrt(pd)/(2*a);
}
else if(pd==0)
{
x1=-b/(2*a);
x2=-b/(2*a);
}
else
{
r=-b/(2*a);
i=sqrt(-pd)/(2*a);
}
}
void funtion::show_value ()
{

if(pd>0)
cout<<"x1="<<x1<<" "<<"x2="<<x2<<endl;
else if(pd==0)
cout<<"x1="<<x1<<" "<<"x2="<<x2<<endl;
else
cout<<"x1="<<r<<'+'<<i<<"i"<<" "<<"x2="<<r<<'+'<<i<<"i"<<endl;
}
int main()
{
funtion f;
f.set_value ();
f.display ();
f.show_value ();
return 0;
}
这问题谁帮提供个解决思路,谢谢!

[此贴子已经被作者于2007-5-6 10:44:45编辑过]

7 回复
#2
幽灵嫖客2007-05-05 23:32
对了,我那个程序,编了一个友元函数也不能访问私有成员:
定义:
ostream & operator<<(ostream & os,const complex & c)
{
os<<"("<<c.real<<" , "<<c.imaginary<<"i)";
return os;
}
说什么cannot access private member declared in class 'complex',
楼主知道是怎么回事不?
#3
weishj2007-05-05 23:38
#4
aipb20072007-05-06 00:50

楼主,不用更新的头文件而使友员能访问到私有成员。这个结论是个bug吧,还是编译器的。对吧?

既然这样,为什么要想办法去迎合这种巧合(可以这样说吧,毕竟那个bug非标准),有什么价值吗?

愚见而已!

#5
幽灵嫖客2007-05-06 07:12

也就是说只能把定义放类声明里面了!

楼上的,小弟还有个问题,我重载了一个输入操作符》,
把它的定义也是放类声明里面的,为什么有这个错误:
friend istream & operator>>(istream & is,const complex & c)
{
cout<<"real: ";
is>>c.real;
cout<<endl<<"imaginary: ";
is>>c.imaginary;
return is;
};

error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'const double' (or there is no acceptable conversion),
这是怎么回事?

#6
aipb20072007-05-06 09:43
楼上的,重载输入操作,右操作数怎么能是const类型呢?你要改变它的值也!
#7
weishj2007-05-06 10:45
版主说的有理,至此可不再讨论,结贴
#8
幽灵嫖客2007-05-06 17:52
以下是引用aipb2007在2007-5-6 9:43:46的发言:
楼上的,重载输入操作,右操作数怎么能是const类型呢?你要改变它的值也!

,const用惯了,产生条件反射了!

1