源码如下,解释在后面。
#includeusing namespace std; class B { public: virtual void f1() { cout << "B:f1()" << endl; } virtual void f2() { cout << "B:f2()" << endl; } void g() { cout << "B:g()" << endl; f1(); f2(); } }; class D :public B { public: virtual void f1() { cout << "D:f1()" << endl; } virtual void f3() { cout << "D:f3()" << endl; } void g() { cout << "D:g()" << endl; f1(); f2(); } }; int main() { D d; D* pd = &d; B* pb = &d; B b = d; b.f1(); b.f2(); b.g(); pb->f1(); pb->f2(); pb->g(); pd->f1(); pd->f2(); pd->f3(); pd->g(); }
对象直接调用自己的成员方法。
因为f1()方法增加了virtual关键字,d为D类的实例化对象,动态链接的方式查表,即使父类指针pb指向子类对象,依然调用子类D的实例化对象d的成员方法。
子类D中没有重写(覆盖)f2()方法,所以使用子类对象的成员方法。
g()方法前没有virtual,所以是静态链接,直接用指针类型B类内的方法,调用f1()时又因为f1()方法有virtural关键字,所以是动态链接,经过后期绑定后找到该指针指向对象的成员方法,打印出,D:f1(),
调用f2()方法时,基类没有f2(),所以使用继承自基类中的方法,java也同理。
删除掉程序内所有virtual关键字后运行结果如下
可以发现两者的结果没有不同,virtual的存在就是为了动态多态,动态链接存在的,但此时指针类型指向了它对应的对象类型,所以二者没有什么差异,方法优先使用自己的成员方法,若类内没有重写的方法,便使用继承的基类的方法。
观察结果,因为只没有f2()方法,所有调用基类的该方法,其他方法自动调用自己的。
要求
#include#include using namespace std; const double PI = 3.1415926; //图形的抽象基类 class Shape { public: virtual double Area() = 0; //求面积, 纯虚函数; }; //求二维图形的抽象基类; class Shape2D :public Shape { public: virtual double Perimeter() = 0; //求周长, 纯虚函数; }; //求三维图形的抽象基类; class Shape3D :public Shape { public: virtual double Volume() = 0; //求体积, 纯虚函数; }; //派生类, 矩形; class Rectangle : public Shape2D { public: Rectangle(double length,double width){ length_=length; width_=width; } virtual double Area(){ return length_*width_; } virtual double Perimeter(){ return 2*length_+2*width_; } double length_; double width_; }; //派生类, 椭圆; class Ellipse :public Shape2D { public: Ellipse(double semimajor,double semiminor){ semimajor_=semimajor; semiminor_=semiminor; } virtual double Area(){ return 2*PI+4*(semimajor_-semiminor_); } virtual double Perimeter(){ return PI*semimajor_*semiminor_; } double semimajor_; double semiminor_; }; //派生类, 圆; class Circle : public Shape2D { public: Circle(double radius){ radius_ = radius; } virtual double Area(){ return PI*radius_*radius_; } virtual double Perimeter(){ return PI*2*radius_; } double radius_; }; //派生类, 球体; class Sphere :public Shape3D { public: Sphere(double radius){ radius_ = radius; } virtual double Area(){ return 4*PI*radius_*radius_; } virtual double Perimeter(){ return 3*PI*radius_*radius_*radius_/4; } double radius_; }; //派生类, 圆柱体; class Cylinder :public Shape3D { Cylinder(double height,double radius){ height_=height; radius_=radius; } virtual double Area(){ return PI*radius_*radius_*2 + PI*2*radius_*height_; } virtual double Volume(){ return PI*radius_*radius_ * height_; } double height_; double radius_; }; //派生类, 圆锥体; class Cone : public Shape3D { public: Cone(double height,double radius){ height_=height; radius_=radius; } virtual double Area(){ return PI*radius_*(radius_+pow(height_*height_+radius_*radius_,0.5)); } virtual double Volume(){ return PI*radius_*radius_ * height_/3; } double height_; double radius_; }; class SumofShape { public: //静态函数 计算图形数组面积之和 static double SumofArea(Shape* shape[], int n) { } //静态函数 计算图形数组周长之和 static double SumofPerimeter(Shape* shape[], int n) { //to do } //静态函数 计算图形数组的体积之和 static double SumofVolume(Shape* shape[], int n) { //to do } private: SumofShape() {} //定义私有构造函数,禁止实例化 }; int main() { Rectangle rectangle(2, 3); Ellipse ellipse(8, 4); Circle circle(3); Sphere sphere(3); Cylinder cylinder(3, 5); Cone cone(3, 4); Shape* shape_array[] = { &rectangle, &ellipse, &circle, &sphere, &cylinder, &cone }; double sum_of_area = SumofShape::SumofArea(shape_array, 6); double sum_of_perimeter = SumofShape::SumofPerimeter(shape_array, 6); double sum_of_volume = SumofShape::SumofVolume(shape_array, 6); cout << "面积总和:" << sum_of_area << "n周长总和:" << sum_of_perimeter << "n体积总和:" << sum_of_volume << endl; return 0; }



