关于友元函数的小问题

#include //声明类Point
using namespace std;
class Point
{
public:
Point(float x=0,float y=0); //有默认参数的构造函数
void setPoint(float ,float); //设置坐标值
float getX( )const {return x;} //读x坐标
float getY( )const {return y;} //读y坐标
friend ostream& operator<<(ostream &,const Point &);
//重载运算符“<<”
protected: //受保护成员
float x, y;
};
//下面定义Point类的成员函数
Point::Point(float a,float b) //Point的构造函数
{ //对x,y初始化
x=a;
y=b;
}
void Point::setPoint(float a,float b) //设置x和y的坐标值
{ //为x,y赋新值
x=a;
y=b;
}
//重载运算符“<<”,使之能输出点的坐标
ostream& operator<<(ostream &cout, const Point &p)
{
cout<<"["<<p.x<<","<<p.y<<"]"<<endl;
return cout;
}
class Circle:public Point //circle是Point类的公用派生类
{
public:
Circle(float x=0,float y=0,float r=0); //构造函数
void setRadius(float ); //设置半径值
float getRadius( )const; //读取半径值
float area ( )const; //计算圆面积
friend ostream &operator <<(ostream &,const Circle &); //重载运算符“<<”
private:
float radius;
};
//定义构造函数,对圆心坐标和半径初始化
Circle::Circle(float a,float b,float r):Point(a,b),radius(r){}
//设置半径值
void Circle::setRadius(float r){radius=r;}
//读取半径值
float Circle::getRadius( )const {return radius;}
//计算圆面积
float Circle::area( )const
{
return 3.14159*radius*radius;
}
//重载运算符“<<”,使之按规定的形式输出圆的信息
ostream &operator <<(ostream &output,const Circle &c)
{
output<<"Center=["<<c.x<<","<<c.y<<"],r="<<c.radius<<",area="<<c.area( )<<endl;
return output;
}
int main( )
{
Circle c(3.5,6.4,5.2); //建立Circle类对象c,并给定圆心坐标和半径
cout<<"original circle:\nx="<<c.getX()<<", y="<<c.getY()<<", r="<<c.getRadius( )<<", area="<<c.area( )<<endl; //输出圆心坐标、半径和面积
c.setRadius(7.5); //设置半径值
c.setPoint(5,5); //设置圆心坐标值x,y
cout<<"new circle:\n"<<c; //用重载运算符“<<”输出圆对象的信息
Point &pRef=c; //pRef是Point类的引用变量,被c初始化
cout<<"pRef:"<<pRef; //输出pRef的信息
return 0;
}

报错内容是(友元函数不能访问保护成员???)
G:\c_files\try_2.cpp(506) : error C2248: 'x' : cannot access protected member declared in class 'Point'
G:\c_files\try_2.cpp(490) : see declaration of 'x'
G:\c_files\try_2.cpp(506) : error C2248: 'y' : cannot access protected member declared in class 'Point'
G:\c_files\try_2.cpp(490) : see declaration of 'y'
G:\c_files\try_2.cpp(534) : error C2248: 'x' : cannot access protected member declared in class 'Point'
G:\c_files\try_2.cpp(490) : see declaration of 'x'
G:\c_files\try_2.cpp(534) : error C2248: 'y' : cannot access protected member declared in class 'Point'
G:\c_files\try_2.cpp(490) : see declaration of 'y'
G:\c_files\try_2.cpp(534) : error C2248: 'radius' : cannot access private member declared in class 'Circle'
G:\c_files\try_2.cpp(518) : see declaration of 'radius'
G:\c_files\try_2.cpp(539) : warning C4305: 'argument' : truncation from 'const double' to 'float'
G:\c_files\try_2.cpp(539) : warning C4305: 'argument' : truncation from 'const double' to 'float'
G:\c_files\try_2.cpp(545) : error C2593: 'operator <<' is ambiguous
执行 cl.exe 时出错.
另有,将point类中重载函数写成inline就不报错了,为什么?

3个回答

友元函数只能访问this,不能访问另一个对象

oqqkid1234
oqqkid1234 那为什么友元函数写成内嵌形式就可以编译通过了呢?
5 年多之前 回复

因为你虽然是友元函数,但是你是通过对象p访问的,它不能访问保护成员,同样受权限限制。

oyljerry
oyljerry 回复oqqkid1234: 虽然是友元函数,但是它还是不能直接访问p.x
5 年多之前 回复
oqqkid1234
oqqkid1234 小弟愚钝,不明白你的意思
5 年多之前 回复
 #include<iostream>
using namespace std;
class Point//声明类Point
{
public:
Point(double x=0,double y=0); //有默认参数的构造函数
void setPoint(double ,double); //设置坐标值
double getX( )const 
{
    return x;
} //读x坐标
double getY( )const 
{
    return y;
} //读y坐标
friend ostream& operator<<(ostream &,const Point &); 
//重载运算符“<<”
protected: //受保护成员
double x, y;
};


//下面定义Point类的成员函数
Point::Point(double a,double b) //Point的构造函数
{ //对x,y初始化
x=a;
y=b;
}
void Point::setPoint(double a,double b) //设置x和y的坐标值
{ //为x,y赋新值
x=a;
y=b;
}
//重载运算符“<<”,使之能输出点的坐标
ostream& operator<<(ostream &cout, const Point &p)
{
cout<<"["<<p.x<<","<<p.y<<"]"<<endl;
return cout;
}


class Circle:public Point //circle是Point类的公用派生类
{
public:
Circle(double x=0,double y=0,double r=0); //构造函数
void setRadius(double ); //设置半径值
double getRadius( )const; //读取半径值
double area ( )const; //计算圆面积
friend ostream &operator <<(ostream &,const Circle &); //重载运算符“<<”
private:
double radius;
};


//定义构造函数,对圆心坐标和半径初始化
Circle::Circle(double a,double b,double r):Point(a,b),radius(r)
{
}
//设置半径值
void Circle::setRadius(double r)
{
    radius=r;
}
//读取半径值
double Circle::getRadius( )const 
{
    return radius;
}
//计算圆面积
double Circle::area( )const
{
    return 3.14159*radius*radius;
}
//重载运算符“<<”,使之按规定的形式输出圆的信息
ostream &operator <<(ostream &output,const Circle &c)
{
    output<<"Center=["<<c.x<<","<<c.y<<"],r="<<c.radius<<",area="<<c.area( )<<endl;
    return output;
}



int main( )
{
Circle c(3.5,6.4,5.2); //建立Circle类对象c,并给定圆心坐标和半径
cout<<"original circle:\nx="<<c.getX()<<", y="<<c.getY()<<", r="<<c.getRadius( )<<", area="<<c.area( )<<endl; //输出圆心坐标、半径和面积
c.setRadius(7.5); //设置半径值
c.setPoint(5,5); //设置圆心坐标值x,y
cout<<"new circle:\n"<<c; //用重载运算符“<<”输出圆对象的信息
Point &pRef=c; //pRef是Point类的引用变量,被c初始化
cout<<"pRef:"<<pRef; //输出pRef的信息
cin.get();
return 0;
}

图片说明

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐