Peronal Link: http://segmentfault.com/a/1190000002464822
这节课讲了本门课程 面向对象程序设计中最为重要的一个部分 - 多态
1 /************************************************************************* 2 > File Name: polymorphism.cpp 3 > Author: Jeremy Wu 4 > Created Time: Mon 25 May 2015 10:04:07 AM CST 5 > Function: tune every instrument 6 ************************************************************************/ 7 8 //多态:一个接口,多种实现 9 //发生多态现象的条件:10 // 1.通过调用虚函数(基类中必须要有,派生类中可有可无建议加上)11 // 2.借助指针或者引用调用该虚函数12 //13 //虚函数只能是 非静态 成员函数14 //如果类中有虚函数,最好把 析构函数 也定义为虚函数15 //16 //如果基类的析构函数是虚函数,由它派生的所有的派生类的析构函数都 自动 成为虚函数17 // ·构造函数无法定义为虚函数18 //19 //基类可以指向它的所有的派生类20 //相当于基类给所有的派生类提供了统一的接口21 //一般不会直接创建基类的对象22 //23 //{ 抽象基类 }24 //如果一个类中包含纯虚函数,就是抽象类25 //抽象类无法创建对象26 //如果需要 避免 创建基类对象,应该使用纯虚函数27 28 29 30 //接下来是一个例子,有一个基类叫做乐器类31 //由它派生出Wind , Brass 和 Gitar 三个类32 33 #include34 35 using namespace std;36 37 class Instrument {38 public:39 virtual void play (); //virtual 关键字40 Instrument () { cout << "Instement () " << endl; }41 virtual ~Instrument () { cout << "~Instement () " << endl; }42 };43 44 void Instrument::play () { //类的外部定义前不用加 virtual 关键字45 cout << "Instrument::play ()" << endl;46 }47 48 class Wind : public Instrument{49 virtual void play () { cout << "Wind::play () " << endl; } //派生类中 virtual 关键字可加可不加50 ~Wind () { cout << "Wind::~Wind ()" << endl; }51 };52 53 class Brass : public Instrument {54 virtual void play () { cout << "Brass::play ()" << endl; }55 ~Brass () { cout << "Brass::~Brass () " << endl; }56 };57 58 class Gitar : public Instrument {59 virtual void play () { cout << "Gitar::play ()" << endl; }60 ~Gitar () { cout << "Gitar::~Gitar ()" << endl; }61 };62 63 //inst 指针在定义的时候,是静态类型64 //在程序运行过程中,它的动态类型就会根据指向对象的类型作改变65 //66 //有时候把动态绑定称为运行时绑定,也称后继绑定67 //run-time binding68 69 void tune (Instrument * inst) { //引用传递 或者用指针70 inst->play (); //Dynamic binding71 //在编译时进行 动态绑定72 }73 74 int main () {75 76 Instrument * p = new Gitar;77 Instrument * p2 = new Wind;78 79 delete p;80 delete p2;81 82 return 0;83 }
接下来老师出了一道题目
描述如下:
以下是我的 Solution:
1 /************************************************************************* 2 > File Name: ployPROB.cpp 3 > Author: Jeremy Wu 4 > Created Time: Mon 25 May 2015 10:50:07 AM CST 5 ************************************************************************/ 6 7 //定义一个形状类的继承结构 8 // 9 //Shape -> Triangle10 // -> Rectangle11 // -> Circle12 //13 //给形状定义两个操作:14 // getArea () 求面积15 // getLength () 求周长16 17 #include18 #include 19 20 const double PI = 3.1415926;21 22 using namespace std;23 24 class Shape {25 public:26 virtual double getArea () = 0; 27 virtual double getLength () = 0;28 virtual ~Shape () { cout << "~Shape ()" << endl; }29 Shape () { cout << "Shape ()" << endl; }30 };31 32 class Triangle : public Shape {33 private:34 double x, y, z;35 public:36 double getArea () { 37 double p = (x + y + z) / 2.0;38 return sqrt (p * (p - x) * (p - y) * (p - z));39 }40 double getLength () { return x + y + z; }41 Triangle (double ix = 0.0, double iy = 0.0, double iz = 0.0) { 42 x = ix, y = iy, z = iz;43 }44 ~Triangle () { cout << "~Triangle () " << endl; }45 };46 47 class Rectangle : public Shape {48 private:49 double x, y;50 public:51 double getArea () { return x * y; }52 double getLength () { return 2.0 * (x + y); }53 Rectangle (double ix = 0.0, double iy = 0.0) {54 x = ix, y = iy;55 }56 ~Rectangle () { cout << "~Rectangle () " << endl; }57 };58 59 class Circle : public Shape {60 private:61 double r;62 public:63 double getArea () { return PI * r * r; }64 double getLength () { return 2.0 * PI * r; }65 Circle (double ir = 0.0) {66 r = ir;67 }68 ~Circle () { cout << "~Circle ()" << endl; }69 };70 71 void test (Shape & sp) {72 cout << "/***********************************/" << endl;73 cout << '\t' << "Area is " << sp.getArea () << endl;74 cout << '\t' << "Length is " << sp.getLength () << endl;75 cout << "/***********************************/" << endl;76 }77 78 int main () {79 80 Circle p1 (3.0);81 Rectangle p2 (3.0, 6.0);82 Triangle p3 (1.0, 2.0, 1.5);83 84 test (p1);85 test (p2);86 test (p3);87 88 return 0;89 }
以下是官方版 Solution:
1 /************************************************************************* 2 > File Name: example.cpp 3 > Author: Jeremy Wu 4 > Created Time: Mon 25 May 2015 11:34:47 AM CST 5 ************************************************************************/ 6 7 #include8 #include 9 10 using namespace std;11 12 class Shape {13 public:14 virtual double area () = 0; //不实现基类可以这么写,表示定义一个纯虚函数15 virtual double zhou () = 0; //pure virtual function16 };17 18 class Triangle : public Shape {19 double a, b, c;20 public:21 Triangle (double aa, double bb, double cc) : a (aa), b (bb), c (cc) {}22 virtual double area () {23 double p = 0.5 * (a + b + c);24 return sqrt (p * (p - a) * (p - b) * (p - c));25 }26 virtual double zhou () {27 return a + b + c;28 }29 };30 31 class Rectangle : public Shape {32 double a, b;33 public:34 Rectangle (double aa, double bb) : a (aa), b (bb) {}35 virtual double area () {36 return a * b;37 }38 virtual double zhou () {39 return 2.0 * (a + b);40 }41 };42 43 class Circle : public Shape {44 double r;45 public:46 Circle (double rr) : r (rr) {}47 virtual double area () {48 return 3.14159 * r * r;49 }50 virtual double zhou () {51 return 2.0 * 3.14159 * r;52 }53 };54 55 void printArea (Shape * p) { 56 cout << p->area () << endl; 57 }58 59 void printZhou (Shape * p) {60 cout << p->zhou () << endl;61 }62 63 int main () {64 65 Shape * p1, * p2, * p3;66 67 //Shape sp;68 69 p1 = new Triangle (6, 7, 8);70 p2 = new Rectangle (10, 4.6);71 p3 = new Circle (5.8);72 73 printArea (p1);74 printArea (p2);75 printArea (p3);76 77 printZhou (p1);78 printZhou (p2);79 printZhou (p3);80 81 return 0;82 }