我在写代码时遇到的一个题目:定义一个抽象类shape,包括公有的计算面积area函数,计算体积volume函数,输出基本信息函数printinfo(三个函数均为纯虚函数)。从shape公有派生point类,增加私有数据成员x,y坐标。从point公有派生circle类,增加私有数据成员半径r数。从circle公有派生cylinder类,增加私有数据成员高度h。在main函数中,定义shape类的指针,指向派生类的对象,输出三类对象的基本信息,面积,体积;
我在如下给出正确代码
#include<iostream>
using namespace std;
#define PI 3.14
class Shape
{
public:
virtual double area()=0;
virtual double volume()=0;
virtual void printinfo()=0;
};
class Point :public Shape
{
public:
Point(double _x,double _y):x(_x),y(_y)
{
}
virtual double area()
{
return 0;
}
virtual double volume()
{
return 0;
}
virtual void printinfo()
{
cout << "x坐标是" << x << endl;
cout << "y坐标是" << y << endl;
}
private:
double x, y;
};
class Circle :public Point
{
public:
Circle(double _r) :Point(0,0), r(_r)
{
}
virtual double area()
{
return PI * r * r;
}
virtual double volume()
{
return 0;
}
virtual void printinfo()
{
cout << "圆的面积" << area() << endl;
}
double getr()
{
return r;
}
private:
double r;
};
class Cylinder :public Circle
{
public:
Cylinder(double _h) :Circle(3),h(_h)
{
}
virtual double area()
{
return 2*PI*getr()* getr() +2*PI*getr() *h;
}
virtual double volume()
{
return PI* getr() * getr() *h;
}
virtual void printinfo()
{
cout << "圆柱的体积" << volume() << endl;
cout << "圆柱的表面积" << area() << endl;
}
private:
double h;
};
void dowork(Shape* p)
{
p->printinfo();
delete p;
}
void Test01()
{
dowork(new Point(1,2));
dowork(new Circle(3));
dowork(new Cylinder(4));
}
int main()
{
Test01();
}
我在写到Circle的构造函数时,我原本是这样写的
Circle(double _r) :, r(_r)
{
}
但是编译器给我报错了,报错显示Point类没有默认构造函数,原因是什么呢,因为我的Circle类是是从Point类派生过来的,在调用Circle类的构造函数时,会先调用Point类的构造函数。但是我在Point类已经设置了一个有参的构造函数,系统也不会再调用Point类的默认构造函数,而且此时你没有调用Point类的有参构造函数,系统也不会再调用Point类的默认构造函数,也所以报错了。
可以改成如下代码
Circle(double _r) :Point(1,2), r(_r)
{
}
如果你希望你之前传入的1和2不变,那么在这里继续可以传1和2,如果你希望重新初始化它们就都改为0。即如果你希望避免这种无意义的初始化(都改为0),可以在Circle类的构造函数中使用初始化列表显式调用Point类的带参构造函数,避免不必要初始化提高代码效率。