多态性之编译期多态和运行期多态(C++版)
1. 编译期多态(静态多态)
- // 例1:函数模板体现出编译期多态
- #include <iostream>
- template <typename T>
- T add(T a, T b)
- {
- T c = a + b;
- return c;
- }
- int main()
- {
- int i1 = 1;
- int i2 = 2;
- int iResult = 0;
- iResult = add(i1, i2);
- std::cout << "The result of integer is " << iResult << std::endl;
- double d1 = 1.1;
- double d2 = 2.2;
- double dResult = 0;
- dResult = add(d1, d2);
- std::cout << "The result of double is " << dResult << std::endl;
- return 0;
- }
从例1中可以看到,我们定义了一个函数模板add,用来求两个数的和,这两个数的数据类型在使用时才知道。main函数中使用了两个int值的求和以及两个double值的求和,这里就体现了多态性,即在编译期,编译器根据一定的最佳匹配算法确定函数模板的参数类型到底是什么,这就体现了编译期的多种状态。
2. 运行期多态(动态多态)
- // 例2:虚函数和继承关系体现运行期多态
- #include <iostream>
- class parent
- {
- public:
- parent() {}
- // 父类的虚函数
- virtual void eat()
- {
- std::cout << "Parent eat." << std::endl;
- }
- // 注意这个并不是虚函数!!!
- void drink()
- {
- std::cout << "Parent drink." << std::endl;
- }
- };
- class child : public parent
- {
- public:
- child () {}
- // 子类重写了父类的虚函数
- void eat()
- {
- std::cout << "Child eat." << std::endl;
- }
- // 子类覆盖了父类的函数,注意由于父类的这个函数
- // 并不是虚函数,所以不存在继承后重写的说法
- void drink()
- {
- std::cout << "Parent drink." << std::endl;
- }
- // 子类特有的函数
- void childLove()
- {
- std::cout << "Child love playing." << std::endl;
- }
- };
- int main()
- {
- parent* pa = new child();
- pa->eat(); // 运行期多态的体现!!!
- pa->drink(); // 这里调用的还是父类的drink,所以并不是多态!!!
- // pa->childLove(); // 编译出错,父类的指针不能调用父类没有的函数
- return 0;
- }
- 运行结果:
- Child eat.
- Parent drink.
例2写得比较完善,说明了很多问题,我们先来看主要的,即多态性的体现。注意,在C++中只能用指针或引用来实现多态,不能通过普通的对象来实现多态,例2中使用的是指针的形式。我们来仔细分析一下。
- // 例3:纯虚函数和继承关系体现运行期多态
- #include <iostream>
- // 父类因为包含纯虚函数,所以该类是抽象类,即不能定义对象
- class parent
- {
- public:
- parent() {}
- // 父类的纯虚函数
- virtual void eat() = 0;
- };
- class child : public parent
- {
- public:
- child () {}
- // 子类重写了父类的纯虚函数
- void eat()
- {
- std::cout << "Child eat." << std::endl;
- }
- };
- int main()
- {
- // parent pa0; // 编译期会出错,因为抽象类不能定义对象
- // 注意抽象类虽然不能定义对象,但是可以定义指针用来指向具体类
- parent* pa = new child();
- pa->eat(); // 运行期多态的体现!!!
- return 0;
- }
- 运行结果:
- Child eat.
例3和例2基本上是一样的,省略了很多函数,这里多态性的体现和例2也是完全一样的,之所以举这个例子是为了解释下抽象类用来实现多态的一个理解误区。从例3中就可以看到,纯虚函数就是一个函数后面加上"=0",而没有任何实现,那么包含纯虚函数的类就自然成为了抽象类,而抽象类是不能定义对象的,这也就是为什么main函数中的第一行会出错。注意,继承抽象类的具体类必须实现抽象类中的纯虚函数,否则也会出错。这里想强调一个误区,很多人觉得既然抽象类不能定义对象,那么main函数中的parent *pa为什么没有出错,这是因为抽象类虽然不能定义对象,但是可以定义指针,用来指向具体类,从而实现多态,一定要分清楚C++中的指针、引用、对象三者之间的关系,不要一概而论。
296



被折叠的 条评论
为什么被折叠?



