文章目录
一、 C++ 多态 【基类指针引起的惨案】
1、多态按字面的意思就是多种形态。
当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C++
多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
2、相同函数名,在不同继承类之间,加上virtual关键字,可以解决指定输出的函数功能。
错误: 没有执行指针指向的对象函数
`Parent class area :
Parent class area :`
1、静态连接
调用函数 area() 被编译器设置为基类中的版本, 这就是所谓的【静态多态】,或【静态链接】 -
函数调用在程序执行前就准备好了。 有时候这也被称为【早绑定】,因为 area() 函数在程序编译期间就已经设置好了。 但现在,让我们对程序稍作修改,在 Shape(基类) 类中,area() 的声明前放置关键字 virtual。
正确://输出对象指针指向的函数内容
`Rectangle class area :
Triangle class area :`
解释:编译器看的是指针的内容,而不是它的类型。
因此,由于 tri 和 rec 类的*对象的地址存储在 shape 中, 所以会调用各自的 area() 函数。
功能强大(懒人功能,一个函数名走遍各个类):有了多态,您可以有多个不同的类,
都带有同一个名称但具有不同实现的函数,函数的参数甚至可以是相同的。
///
2、虚函数 是在基类中使用关键字 virtual 声明的函数。
在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接(相同函数名被编译器设置为基类的版本)到该函数。
3、动态连接
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
4、纯虚函数:格式:virtual int area() = 0;
在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
举例:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};
= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数。 如果一个类里面存在有纯虚函数,那么我们把此类称为抽象类
抽象类是不能创建对象
,需要被继承以后,需要把纯虚函数实现,才能创建对象
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0):width(a),height(b)
{
}
//纯虚函数
//virtual int area() = 0;
//虚函数
virtual int area()
{
cout << "基类Shape class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
virtual int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
virtual int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// 程序的主函数
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// 存储矩形的地址
shape = &rec;
// 调用矩形的求面积函数 area
shape->area();
// 存储三角形的地址
shape = &tri;
// 调用三角形的求面积函数 area
shape->area();
return 0;
}
结果说明
PS C:\Users\newuser\Desktop\C++\第六天C++> g++ .\T多态C++.cpp
PS C:\Users\newuser\Desktop\C++\第六天C++> ./a
Rectangle class area :
Triangle class area :
两种方法解决
函数同名同参
的办法:
方法1
基类和派生类都加virtual关键字
方法2
基类定义为virtual int func()=0
;形式
二、多态说明
多态必须依赖虚函数 虚函数解决函数同名 纯虚函数在基类定义[解决函数同名] ,这类也称为抽象类
错误:
基类不要virtual关键字,派生类有virtual修饰函数。
知识拓展:
抽象类:无法创建对象,需要子类实现基类纯虚函数。 如果一个类里面存在有纯虚函数,那么我们把此类称为抽象类
抽象类是不能创建对象,需要被继承以后,需要把纯虚函数实现,才能创建对象
三、静态联编和动态联编
1、
静态联编
:在程序编译期间就能确定的具体的函数调用,如函数重载
;
2、动态联编
:在程序运行期间才能确定的具体的函数调用,如函数重写
。