【预备工作:给出一个示例】
//例:使用成员函数、友元函数和一般函数的区别 #include <iostream> using namespace std; class Time {public: Time(int h,int m,ints):hour(h),minute(m),sec(s){} void display1(); //成员函数声明 friend voiddisplay2(Time &); //友元函数声明 int getHour(){returnhour;} intgetMinute(){return minute;} int getSec(){returnsec;} private: int hour; int minute; int sec; }; void display3(Time &); //一般函数声明 void Time::display1() //成员函数的实现,dispaly1前加Time:: { //以hour形式直接访问私有数据成员,实质是this->hour形式 cout<<hour<<":"<<minute<<":"<<sec<<endl; } void display2(Time &t) //友元函数的实现,dispaly2前不加Time::,并不是类的成员函数 { //不是类的成员函数,却可以t.hour的形式直接访问私有数据成员——友元 cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl; } void display3(Time &t) //一般函数的实现,dispaly1前加Time:: { //只能用公共接口t.getHour()形式访问私有数据成员 cout<<t.getHour()<<":"<<t.getMinute()<<":"<<t.getSec()<<endl; } int main() { Time t1(10,13,56); t1.display1(); //成员函数这样调用 display2(t1); //友员函数调用和一般函数无异 display3(t1); //一般函数的调用 system("pause"); return 0; }
【要完成的任务】阅读上面的程序,仔细阅读注释。然后模仿完成求点类中距离的任务。
你需要完成的任务是,利用成员函数、友元函数和一般函数,实现三个版本的求两点间距离的函数,并设计main()函数完成测试。此任务和上例的区别在于“距离是一个点和另外一个点的距离”,参数个数上有体现。下面是点类的部分代码。
class CPoint { private: double x; // 横坐标 double y; // 纵坐标 public: CPoint(doublexx=0,double yy=0):x(xx),y(yy){} ……//请继续写需要的代码 };
【参考解答】
#include<iostream> #include<Cmath> using namespace std; class CPoint { private: double x; // 横坐标 double y; // 纵坐标 public: CPoint(double xx=0,double yy=0):x(xx),y(yy){} double distance1(CPoint &); //参数用const CPoint &更佳 friend double distance2(CPoint &, CPoint &) ; double getX(){return x;} double getY(){return y;} }; double distance3(CPoint &,CPoint &) ; double CPoint::distance1(CPoint &p) { double dx=(x-p.x), dy=y-p.y; return sqrt(dx*dx+dy*dy); } double distance2(CPoint &p1,CPoint &p2) { double dx=(p1.x-p2.x), dy=p1.y-p2.y; return sqrt(dx*dx+dy*dy); } double distance3(CPoint &p1,CPoint &p2) { double dx=(p1.getX()-p2.getX()), dy=p1.getY()-p2.getY(); return sqrt(dx*dx+dy*dy); } int main() { CPoint p1(10,13), p2(-5,6); cout<<"1. "<<p1.distance1(p2)<<endl; cout<<"2. "<<distance2(p1,p2)<<endl; cout<<"3. "<<distance3(p1,p2)<<endl; system("pause"); return 0; }
许是受了示例的影响,一些同学设计了如下的程序:
#include<iostream> #include<Cmath> using namespace std; class CPoint { private: double x; // 横坐标 double y; // 纵坐标 public: CPoint(double xx=0,double yy=0):x(xx),y(yy){} void distance1(CPoint &); friend void distance2(CPoint &, CPoint &) ; double getX(){return x;} double getY(){return y;} }; void distance3(CPoint &,CPoint &) ; void CPoint::distance1(CPoint &p) { double dx=(x-p.x), dy=y-p.y; cout<<sqrt(dx*dx+dy*dy)<<endl;//计算距离并直接输出 } void distance2(CPoint &p1,CPoint &p2) { double dx=(p1.x-p2.x), dy=p1.y-p2.y; cout<<sqrt(dx*dx+dy*dy)<<endl; //计算距离并直接输出 } void distance3(CPoint &p1,CPoint &p2) { double dx=(p1.getX()-p2.getX()), dy=p1.getY()-p2.getY(); cout<<sqrt(dx*dx+dy*dy)<<endl; //计算距离并直接输出 } int main() { CPoint p1(10,13), p2(-5,6); cout<<"1. 使用成员函数"; p1.distance1(p2); cout<<"2. 使用友元函数"; distance2(p1,p2); cout<<"3. 使用一般函数"; distance3(p1,p2); system("pause"); return 0; }
是否完成了任务?不可否认。但是,在计算距离的函数中直接输出结果,函数返回值类型为void型的做法很不专业。distance函数的功能是求距离,“求”距离,也即得到一个距离值即可,我们需要围绕这一语义设计函数,其结果就应该是一个值,表示距离的值。所以,求出了距离,很自然地将距离作为返回值即可。至于这个值如何利用,是调用distance函数的人需要考虑的事情了。举一例说明,比如给出三点构成三角形,要求周长,求边长——两点间的距离是不可回避的事情,这时求得的距离就不是输出就行了,而是返回值再去参与其他运算。
所以,在设计函数时一般有个原则:函数中尽可以不涉及输入和输出。必要的入口数据由参数给出,而计算结果通过返回值返回,当结果不止一个时,往往通过指针或引用给出。