8-虚函数与多态

时间:2022-11-23 21:53:58

 

 1 //继承中对象.cpp
 2 #include<iostream>
 3 using namespace std;
 4 
 5 class A
 6 {
 7 private:
 8     int a;
 9 public:
10      A(int i = 0){ a = i; }
11       void print()
12     {
13         cout << "Print::a" << endl;
14     }
15 };
16 
17 class B :public A
18 {
19 public:
20     B(int j = 1) :b(j){}
21 
22 private:
23     int b; 
24 };
25 //前提是:类外函数
26 //把派生类对象当作基类来处理
27 void Print(A &a)
28 {
29     a.print();
30 }
31 int main()
32 {
33     A a;
34     Print(a); 
35     B b;
36     Print(b);
37     system("pause");
38     return 0;
39 }
 1 //虚析构函数.cpp
 2 #include <iostream>
 3 using namespace std;
 4 class B
 5 {
 6 public:
 7     virtual ~B()
 8     {
 9         cout << "B::~B()" << endl;
10     }
11 };
12 class D :public B
13 {
14 public:
15     ~D()    //也是虚函数
16     {
17         cout << "D::~D()" << endl;
18     }
19 };
20 int main()
21 {
22     B *p;
23     p = new D;        //派生类无名对象初始化基类指针
24     delete p;        //销毁无名对象,释放存储空间
25     system("pause");
26     return 0;
27 }
 1 //纯虚函数.cpp
 2 // virtual 函数类型 函数名(参数) =0;  没有函数体 纯虚函数--->抽象类  不能创建对象  ADT过程
 3 #include <iostream>
 4 using namespace std;
 5 class Shape
 6 {
 7 protected:
 8     double x, y;
 9 public:
10     void set(double xx, double yy)
11     {
12         x = xx;
13         y = yy;
14     }
15     
16     /*Shape(double x=5, double y=2.0) :x(x), y(y){}*/    //自己写的构造函数  测试
17     virtual void area() = 0;//纯虚函数
18 };
19 class Triangle :public Shape
20 {
21 public:
22     void area()
23     {
24         cout << "三角形的面积:" << 0.5*x*y << endl;
25     }
26 };
27 class Rectangle : public Shape
28 {
29 public:
30     void area()
31     {
32         cout << "矩形面积:" << x*y << endl;
33     }
34 };
35 int main()
36 {
37     Shape *p ;
38     
39     Triangle t;
40     Rectangle r;
41     
42     //p = &t;               //构造函数的测试
43     //p->area();
44 
45     p = &t;
46     p->set(5, 2.0);
47     p->area();
48 
49     p = &r;
50     p->set(5, 4.0);
51     p->area();
52 
53     system("pause");
54     return 0;
55 }
 1 //基类指针.cpp
 2 
 3 //基类指针的使用
 4 //基类指针访问基类成员
 5 //派生指针访问派生类成员
 6 #include<iostream>
 7 using namespace std;
 8 class Base
 9 {
10 public:
11     Base(int age=2015) :age(age){}
12 
13     //声明虚函数 virtual
14     virtual void show()
15     {
16         cout << "Base::age" << age << endl;
17     }
18     void show2()
19     {
20         cout << "Base::show()2" << endl;
21     }
22 private:
23     int age;
24 };
25 class Data:public Base
26 {
27 public:
28     Data(int data = 2016) :age(data){}
29     void show()
30     {
31         cout << "Data::age" << age << endl;
32     }
33     void showage()
34     {
35         cout << "showage()" << endl;
36     }
37 private:
38     int age;
39 };
40 
41 
42 //多态体现二:引用
43 class Data2:public Base
44 {
45 public:
46     Data2(int age = 2014) :age(age){}
47     void show()
48     {
49         cout << "Data2::show()" << endl;
50     }
51 private:
52 
53     int age;
54 };
55 int main()
56 {
57 
58     //Object 是对象
59     Base *pB, BObject;
60     pB = &BObject;
61     BObject.show();
62     pB->show();  //基类中age
63 
64 
65 
66     //多态的体现,----->virtual
67     //派生类对象初始化基类指针
68     //多态体现之一:
69     Base *pD = new Data;
70     pD->show();        //派生类中show    注意不加virtual 会调用基类的show
71     pD->show2();
72 
73     //多态体现二:引用
74     Base *pB2;
75     Data2 Dobject2;
76     pB2 = &Dobject2;
77     pB2->show();
78 
79     //存在虚函数
80     //基类指针调用的是什么成员
81     //被那个对象初始化,就是调用哪个对象中的成员
82 
83     //注意点:
84     //1.没有virtual 的构造函数
85     //2.如果没有virtual 基类会覆盖掉子类中的同名同参函数
86     //3.virtual 不能是非成员函数,也不是友元类
87     //4.virtual函数永远都是虚函数,无论被继承多少层
88     system("pause");
89     return 0;
90 }
 1 //dynamic_cast.cpp
 2 
 3 //        dynamic_cast<type_id>(expression)
 4 //      作用:实现子类和父类之间的多态类型转换
 5 /*
 6 注意点:
 7         1.与static 是相对应,运行时进行类型转换
 8         2.expression中必须有虚函数,没有编译器出错
 9 执行过程:
10     <1>.编译先检测是否有虚函数
11     <2>.数据转换,运行过程做一个判断
12 根据类之间的关系,可以分为三种情况:
13         1.子类到基类转换  ------>上行转换
14         2.基类到子类的转换------>下行转换
15         3.多个基类不同子类之间相互转换 ---->交叉转换
16 */
17 
18 
19 #include <iostream>
20 using namespace std;
21 class Base
22 {
23 public:
24     virtual void BaseA()
25     {
26         cout << "Base::BaseA()" << endl;
27     }
28     virtual void Print()
29     {
30         cout << "Base::Print()" << endl;
31     }
32     virtual void PrintA()
33     {
34         cout << "Base::PrintA()" << endl;
35     }
36 };
37 class Derived :public Base
38 {
39 public:
40     virtual void DerivedA()
41     {
42         cout << "Derived::DerivedA()" << endl;
43     }
44     virtual void Print()
45     {
46         cout << "Derived::Print()" << endl;
47     }
48     void PrintA()
49     {
50         cout << "Derived::PrintA()" << endl;
51     }
52 };
53 int main()
54 {
55     //创建派生指针用派生类对象初始化
56     Derived *pD = new Derived;    
57 
58     //正常情况
59     //派生类对象初始化基类指针
60     Base *pB = dynamic_cast<Derived *>(pD);
61     
62     pD->BaseA();
63     pB->BaseA();  //基类指针调用基类虚函数BaseA()
64     pB->Print();  //看基类指针初始化的类
65     cout << endl;
66 
67     //为了实现虚函数的作用,让基类指针指向派生对象
68     Base* pBase0 = new Derived;
69     pBase0->PrintA();  
70 
71     
72     
73     
74     //pBase0->DerivedA(); 基类指针无法访问派生成员
75     //转换后可以进行访问
76     Derived *pDerived = dynamic_cast<Derived*>(pBase0);
77     pDerived->DerivedA(); 
78     pBase0->PrintA();
79     cout << endl;
80 
81     Base *pBB = static_cast<Derived*>(pD);
82     pBB->BaseA();
83     pBB->Print();
84     cout << endl;
85 
86 
87     //不用转换
88     //初始化对象确定调用哪一个成员
89     Base *pBBB = pD;
90     pBBB->BaseA();
91     pBBB->Print();
92     cout << endl;
93 
94     system("pause");
95 
96     return 0;
97 }

 

作业:

  1 //08作业.cpp
  2 
  3 /*******头文件*******/
  4 #include<iostream>
  5 #include<stdio.h>
  6 using namespace std;
  7 
  8 /*******静态变量*******/
  9 static double SW = 0; //保存标准体重 
 10 
 11 /*******函数声明区*******/
 12 void Welcome();      //菜单
 13 void CalMBHI();      //计算男子BMI
 14 void CalWBHI();      //计算女子BMI 
 15 
 16 /*******基类:Person类*******/
 17 class Person
 18 {
 19 protected:
 20     double Height;   //身高
 21     double Weight;   //体重
 22 public:
 23     Person(){};
 24     Person(double height, double weight) :Height(height), Weight(height){}
 25     void Input()                         //成员函数,实现键盘输入数据
 26     {
 27         cin >> Height >> Weight;
 28     }
 29     virtual void StandardWeight() = 0;   //纯虚函数,求标准体重,全局静态变量保存
 30     virtual void BMI();                  //成员函数声明
 31 };
 32 
 33 //判断身体健康程度
 34 void Person::BMI()
 35 {
 36     if (Weight < SW*0.9)
 37     {
 38         cout << "当前身体健康程度:偏瘦" << endl;
 39     }
 40     else if (Weight >= SW*0.9&&Weight <= SW*1.1)
 41     {
 42         cout << "当前身体健康程度:正常" << endl;
 43     }
 44     else if (Weight >SW*1.1&&Weight <= SW*1.2)
 45     {
 46         cout << "当前身体健康程度:偏重" << endl;
 47     }
 48     else if (Weight >SW*1.2&&Weight <= SW*1.3)
 49     {
 50         cout << "当前身体健康程度:轻度肥胖" << endl;
 51     }
 52     else if (Weight >SW*1.3&&Weight <= SW*1.5)
 53     {
 54         cout << "当前身体健康程度:中度肥胖" << endl;
 55     }
 56     else
 57     {
 58         cout << "当前身体健康程度:重度肥胖" << endl;
 59     }
 60 }
 61 
 62 /*******派生类:Man类*******/
 63 class Man :public Person
 64 {
 65 public:
 66     void StandardWeight()
 67     {
 68         SW = (Height - 80)*0.7;
 69     }
 70 };
 71 
 72 /*******派生类:Woman类*******/
 73 class Woman :public Person
 74 {
 75 public:
 76     void StandardWeight()
 77     {
 78         SW = (Height - 70)*0.6;
 79     }
 80 };
 81 
 82 /*******主函数*******/
 83 int main()
 84 {
 85     int choice;
 86     do
 87     {
 88         system("cls");
 89         Welcome();
 90         scanf("%d", &choice);
 91         fflush(stdin);
 92 
 93         switch (choice)
 94         {
 95         case 1:CalMBHI(); fflush(stdin); getchar(); break;
 96         case 2:CalWBHI(); fflush(stdin); getchar(); break;
 97         case 0:return 0;
 98         default:printf("选择无效,请重新输入"); fflush(stdin); break;
 99         }
100 
101     } while (choice != 0);
102 
103     system("pause");
104     return 0;
105 }
106 
107 /*******菜单*******/
108 void Welcome()
109 {
110     printf("\n\n"
111         "\t\t********************************************\n"
112         "\t\t*                                          *\n"
113         "\t\t*             BMI健康指数计算              *\n"
114         "\t\t*                                          *\n"
115         "\t\t********************************************\n"
116         "\t\t*                                          *\n"
117         "\t\t*             1.男子BMI计算                *\n"
118         "\t\t*                                          *\n"
119         "\t\t*             2.女子BMI计算                *\n"
120         "\t\t*                                          *\n"
121         "\t\t*             0.退出计算                   *\n"
122         "\t\t*                                          *\n"
123         "\t\t********************************************\n");
124     printf("请选择计算方式:\n   ");
125 }
126 
127 /*******男子BMI计算*******/
128 void CalMBHI()
129 {
130     Person *pm = new Man;
131     cout << "\t男子标准体重公式 =(身高-80)* 70% " << endl;
132     cout << "__________________________________________\n 输入男子身高(cm)、体重(kg):\n  ";
133     pm->Input();
134     pm->StandardWeight();
135     cout << "\t标准体重 SW = " << SW << "kg\n__________________________________________" << endl;
136     pm->BMI();
137 }
138 
139 /*******女子BMI计算*******/
140 void CalWBHI()
141 {
142     Person *pw = new Woman;
143     cout << "\t女子标准体重公式 =(身高-70)* 60% " << endl;
144     cout << "__________________________________________\n 输入女子身高(cm)、体重(kg):\n  ";
145     pw->Input();
146     pw->StandardWeight();
147     cout << "\t标准体重 SW = " << SW << "kg\n__________________________________________" << endl;
148     pw->BMI();
149 }