先建立一个 Point(点)类,包含数据成员x,y(坐标点)。以它为基类,派生出一个Circle(圆)类, 增加数据成员r(半径)。再以Circle类为直接基类,派生出一个Cylinder(圆柱体)类,再增加数据成员h(高)。要求编写程序,重载运算符“<<”和“>>”使之能用于输出以上类对象
#includeusing namespace std; class Point { public: Point(float a = 0, float b = 0);//带默认参数的构造函数 void setpoint(float, float);//设置坐标值 float getX() const { return x; }//设置常成员函数读取x值, 只能读取成员变量的值不能修改 float getY() const { return y; }//格式: 返回类型 成员函数名(参数列表)const; friend ostream& operator<<(ostream&, const Point&);//定义友元函数重载流插入运算符,不能作为成员函数进行重载 格式: ostream& operator<<(ostream&,自定义类&) protected: float x, y; }; Point::Point(float a, float b)//定义Point类构造函数并对x,y初始化 { x = a; y = b; } void Point::setpoint(float a, float b)//定义成员函数 { x = a; y = b; } ostream& operator<<(ostream& output, const Point& p)//定义<<重载函数,定义一个Point类的常对象成员 {//重载流插入和流输出可输入输出自定义的类对象 output << "[" << p.x << "," << p.y << "]" << endl; return output;//作用:能连续向输出流插入信息,实际上output是cout的别名,即return cout 保留输出流的现状 } class Circle :public Point//point为基类 { public: Circle(float a=0, float b=0, float r= 0):Point(a,b),radius(r){}//带默认参数构造函数并初始化 void setradius(float r) { radius = r; }//设置半径r值 float getR()const { return radius; }//获取r值 float area()const;//计算圆面积 friend ostream& operator<<(ostream&, const Circle&);//重载<<流提取运算符 protected: float radius; }; float Circle::area()const//定义常成员函数area {return 3.14 * radius * radius;}//返回值为圆面积 ostream& operator<<(ostream& output,const Circle& q)//定义重载运算符函数 { output << "center=[" << q.x << "," << q.y << "],r=" << q.radius << ",area=" << q.area() << endl; return output; } class Cylinder :public Circle { public: Cylinder(float a=0,float b=0,float r=0,float h=0):Circle(a,b,r),height(h){} void seth(float h){ height = h; } float getH()const { return height; } float area()const;//计算表面积,同名函数 根据同名覆盖的原则t.area()调用的是cylinder类的area函数而不是circle。注:不属于函数重载,因为函数名,函数类型,参数个数均相同。 float volume()const;//计算体积 friend ostream& operator<<(ostream&, const Cylinder&); protected: float height; }; float Cylinder::area()const { return 2 * Circle::area() + 2 * 3.14 * radius * height; } float Cylinder::volume()const { return Circle::area() * height; } ostream& operator<<(ostream& output, const Cylinder& t) { output << "center:[" << t.x << "," << t.y << "]," << "r=" << t.radius << ",h=" << t.height << "narea:" << t.area() << ",volume:" << t.volume() << endl; return output; } //测试程序,测试Point类 int main() { Point p(3.5, 6.4); cout << "x=" << p.getX() << ",y=" << p.getY() << endl; p.setpoint(8.5, 6.8); cout << "p(new):" << p << endl;//使用重载运算符<<自定义数据类型的对象p } //测试circle类 int main() { Circle q(3.5, 6.4, 5.2);//定义circle类的对象q并赋值 cout << "x=" << q.getX() << ",y=" << q.getY() << ",r=" << q.getR() << "narea=" << q.area() << endl;//分别输出 q.setpoint(5, 5);//调用继承的setpoint成员函数设置圆心值 q.setradius(7.5);//调用派生类新增setradius成员函数设置半径值 cout << "new circle:" << q;//用重载运算符<<使用对象q输出圆对象信息 Point& pf = q;//pf是point类的引用,用q对其进行初始化。派生类对象可以代替基类对象向基类对象的引用初始化或赋值。circle为point的公用派生类,所以pf不能等同于q的别名,只是得到了q的起始地址,只是q中基类部分的别名。 cout << "pf:" << pf;//由于pf只是q中基类部分的别名,所以调用的是point类中声明的重载运算符函数,输出的是点的信息而不是圆。 return 0; } //测试cylinder类 int main() { Cylinder t(3.5, 6.4, 5.2, 10); cout << "x=" << t.getX() << ",y=" << t.getY() << ",r=" << t.getR() << ",h=" << t.getH() << "narea=" << t.area() << ",volume=" << t.volume() << endl; t.seth(15); t.setradius(7.5); t.setpoint(5, 5); cout << "new:" << t;//调用cylinder类中的重载运算符函数 Point& pf = t;//用对象t对其进行初始化 cout << "pf:" << pf;//调用point类的重载运算符函数,所以输出point类的内容 Circle& qf = t;//qf是circle类的引用,用t对其进行初始化 cout << "qf:" << qf;//调用circle类的重载运算符函数,所以输出circle类的内容 return 0; }



