c++多态的含义

1.什么是多态?
(1)通过继承同一个基类,产生相关的不同派生类,与基类中同名的成员函数在不同的派生类中会与不同的实现,也就是说:一个接口、多种方法。
(2)多态是面向对象的重要技术之一,它是一种行为的封装,是同一个事物所表现出来的多种形态,简单地说就是:一个接口、多种形态。
(3)现在,运行时使用同一个成员名调用类对象的成员函数,会调用哪个对象的成员函数呢?这就是多态解决的问题。
2.多态的作用
(1)多态技术允许将基类指针或基类引用指向派生类
(2)把不同派生类的对象都当作基类对象来看待,可以屏蔽不同派生类之间的差异,从而写出通用的代码以适应需求的不断变化。
3.多态的分类
(1)多态分两类
》一种是静态多态,通过函数重载或者运算符重载实现。
》一种是动态多态,是只运行的时候的多态,通过虚函数与基类指针共同作用实现
4.在C++中如何实现多态
(1)在C++中,基类指针是指向基类对象的,如果用它来指向派生类对象,则进行指针类型转换(上行转换),将派生类指针转换为基类指针,所以改制真将会指向派生类对象中的积累部分,通过该指针是无法调用派生类对象中的成员函数的。
但是,虚函数突破了这一限制。在派生类的基类部分中,派生类的虚函数取代了基类原来的同名虚函数,因此在使用基类指针指向派生类对象后,使用该基类指针调用这个同名函数成员时就调用了派生类的虚函数。
(2)当把基类的某个成员函数声明为虚函数时,C++允许在其派生类中对该虚函数进行重新定义,赋予它新的功能,并且可以通过基类指针指向不同派生类的对象,来调用相应派生类中该同名虚函数。
由虚函数实现的动态多态性就是:同一类族中不同派生类对象,对同一函数调用作出不同的响应
(3)虚函数的使用方法如下:
》在基类中使用virtual关键字声明成员函数为虚函数(这样就可以在派生类中对该虚函数进行重新定义,赋予它新的功能)
》在派生类中重新定义此虚函数,要求函数名、形参列表、返回值类型均要与基类的虚函数相同,并根据具体需要重新定义它的函数题。
(4)C++规定,当一个成员函数被定义为虚函数后,其派生类中的同名函数都自动称为虚函数

“`
class base
{
public:
base(int a) :b(a){}
void my()
{
cout << “mybase” << endl;
}
virtual void fun()
{
cout << “i am a base” << endl;
}
private:
int b;
};

class child1 :public base
{
pubilc:
child1(int a1, int a2) : base(a1), c1(a2){}
void my()
{
cout << “mychild.” << endl;
}
virtual void fun()
{
cout << “I am a child1.” << endl;
}
private:
int c1;
};

class child2 :public base
{
pubilc:
child2(int a1, int a2) : base(a1), c2(a2){}
void my()
{
cout << “mychild.” << endl;
}
virtual void fun()
{
cout << “I am a child2.” << endl;
}
private:
int c2;
};

base *bptr;
child1 c1(10, 1);

child2 c2(10, 2);

bptr=&c1;//语句1:基类指针指向派生类对象child1
bptr->fun();//语句2,调用的是child1中的func;

c1.fun();//派生类
bptr->my();//基类
c1.my();//派生类

bptr = &c2;//语句3:基类指针指向派生类对象child2;
bptr->fun();//语句4:调用的是child2中的fun();

c2.fun();

bptr->my();//

5.虚函数与纯虚函数的区别与联系
(1)应该考虑:对成员函数的调用是通过对象名还是通过基类指针引用去访问。如果是后两者,则应当声明为虚函数。
(2)虚函数:如果一个类中定义了虚函数virtual,那么这个虚函数是被实现的,起作用就是为了让该虚函数在这个类中的派生类中被覆盖,被实现为不同的功能,从而结合基类指针以实现动态多态性。
(3)纯虚函数:有时定义一个虚函数时,并不定义其函数体,即他的函数体是空的,它的作用只是保留一个虚函数名,他关注的是接口的统一性,其具体功能实现由他的派生类完成。
比如:virtual float area(float a,float b)=0;

最后面的“=0”的作用仅仅只是告诉编译器这是一个纯虚函数。
纯虚函数只具有函数的名称,没有函数体,不具备函数功能,因此不能被调用。只有在其派生类中被重新定义后才具备函数功能,才能被调用。
如果在一个类中声明了纯虚函数,但是在其派生类中该纯虚函数并没有被定义,那么该虚函数在这个派生类中仍然为纯虚函数,仍然不具备函数的功能。
(4)抽象类与抽象基类:不用来定义对象而只作为一种基本类型用作被继承的类,称为抽象类;由于他经常用来作基类,故又称为抽象基类。凡是包含纯虚函数的类,都是抽象类,这种累不能直接生成对象,他的作用就是作为一个类族的共同基类,或者说为一个类族提供一个公共接口。
(5)需要说明的是,使用虚函数,系统要有一定的开销。当一个类中含有虚函数时,编译系统会为他构造一个虚函数指针vptr(4字节),同时这个虚函数指向一个虚函数表,虚函数表示一个指针数组,存放的是该类中的每个虚函数的入口地址。

6.虚析构函数的作用
(1)当派生类的对象从内存中撤销的时候,一般先调用派生类的析构函数释放该对象中的派生部分,再调用基类的析构函数释放该对象的基类部分,从而完整的释放该对象内存。
(2)但是,当用基类指针指向了一个派生类对象,即 base *bptr = new child;此时用delete bptr;来撤销bptr指向的动态存储空间时,只会执行基类的析构函数来释放该堆内存中的基类部分,但是并不会执行派生类的析构函数来释放该内存中的派生类部分。此时就会造成内存泄露现象。
(3)为了避免此类现象发生,我们将基类的析构函数声明为虚析构函数,这样就解决了上述问题(即先调用派生类的析构函数释放该动态空间中的派生类部分,在调用基类的析构函数释放该动态空间中的基类部分,从而能够完整的释放该堆内存。)
(4)如果将基类的析构函数声明为虚析构函数,那么该基类的所有派生类的析构函数都自动生成为虚析构函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值