多态性是指一种事物的多种形态 即对同一函数调用不同的类对象 会做出不同的响应
能具体的说以一下两者的关系吗 ?我看书上的介绍 到是会用虚函数 可是概念上 有些不太清楚
还有当用指向基类对象的的指针指向用new运算符建立的派生类对象
再用该指针作为delete 的参数释放内存的时候只会执行基类的析构函数 因为它是指向派生类对象的基类部分的 那是否就意味着只释放了基类部分的内存呢?
派生类与基类函数的同名“覆盖” 在调用同名函数时是否也属于多态?
如果在同一类中 存在重载函数 那么在调用时 是要根据实参的个数或类型来判断的 那么时候是否也属于同一种调用形式 ? 是否是多态?
C++多态性与联编
答案:2 悬赏:40 手机版
解决时间 2021-03-07 17:30
- 提问者网友:鐵馬踏冰河
- 2021-03-07 05:39
最佳答案
- 五星知识达人网友:神鬼未生
- 2021-03-07 06:33
1. 多态是面向对象编程的一种概念,虚函数是c++多态特性的体现。重载,覆盖,模板都不属多态特性的体现。
2. 无论是delete基类还是派生类指针,delete会释放对象的直接内存(即sizeof的部分),而间接内存(对象的指针成员指向的内存)是需要析构函数主动释放的,因此在delete基类指针时会有两种情况:如果基类析构函数是虚函数,会先调用下一级派生类的析构函数,再调用基类的;如果基类析构函数不是虚函数,就只会调用基类析构函数,这时属于派生类的间接内存会得不到释放造成内存泄露。
2. 无论是delete基类还是派生类指针,delete会释放对象的直接内存(即sizeof的部分),而间接内存(对象的指针成员指向的内存)是需要析构函数主动释放的,因此在delete基类指针时会有两种情况:如果基类析构函数是虚函数,会先调用下一级派生类的析构函数,再调用基类的;如果基类析构函数不是虚函数,就只会调用基类析构函数,这时属于派生类的间接内存会得不到释放造成内存泄露。
全部回答
- 1楼网友:动情书生
- 2021-03-07 06:45
c++中的多态(虽然多态不是c++所特有的,但是c++中的多态确实是很特殊的)分为静多态和动多态(也就是静态绑定和动态绑定两种现象),静动的区别主要在于这种绑定发生在编译期还是运行期,发生在编译期的是静态绑定,也就是静多态;发生在运行期的则是动态绑定,也就是动多态。
静多态可以通过模板和函数重载来实现(之所说c++中的多态主要还是因为模板这个东西),下面举两个例子:
1)函数模板
template<typenamet>
tmax(constt&lsh,constt&rhs)
{
return(lsh>rhs)?lsh:rhs;
}
返回两个任意类型对象的最大值(对象),前提是该类型能够使用>运算符进行比较,并且返回值是bool类型。
使用:
inta=3;intb=4;
cout<<max(a,b)<<endl;
floatc=2.4;floatd=1.2;
cout<<max(c,d)<<endl;
输出结果为:
4
2.4
这种绑定发生在编译期,这是由于模板的实例化是发生在编译期的,即在编译时编译器发现你调用max(a,b)时就自动生成一个函数
intmax(constint&lsh,constint&rhs)
{
return(lsh>rhs)?lsh:rhs;
}
即将所有的t替换成int;
当你调用max(c,d)时就自动生成一个函数
floatmax(constfloat&lsh,constfloat&rhs)
{
return(lsh>rhs)?lsh:rhs;
}
之所以说开始的函数定义是函数模板,就是因为他就像个模子似的,你可以用铝作为原料也可以用石膏或者铜。
2)函数重载:
intmax(inta,intb)
{
return(a>b)?a:b;
}
intmax(inta,intb,intc)
{
returnmax(max(a,b),c);
}
两个函数名称一样,参数类型或个数不完全相同,返回值一样(这个不重要)。
使用:
inta=3,b=4,c=5;
cout<<max(a,b)<<endl;
cout<<max(a,b,c)<<endl;
输出结果为:
4
5
确定函数的过程也发生在编译器,当你使用max(a,b),编译器发现只有两个参数,那么就调用只有两个参数的函数版本,当使用max(a,b,c)时,编译器则使用有3个参数的版本。
通过上面的两个例子,你还可以使用更为方便的模板函数重载:
template<typenamet>
tmax(constt&lsh,constt&rhs)
{
return(lsh>rhs)?lsh:rhs;
}
template<typenamet>
tmax(constt&a,constt&b,constt&c)
{
returnmax(max(a,b),c);
}
使用
floata=3.6,b=1.2,c=7.8;
cout<<max(a,b,c)<<endl;
输出:
7.8
通过参数个数和类型,编译器自动生成和调用对应得函数版本!
动多态则是通过继承、虚函数(virtual)、指针来实现。
classa{
public:
virtualvoidfunc()const{
coust<<“a::func()”<<endl;
}
}
classb:publica{
public:
virtualvoidfunc()const{
coust<<“b::func()”<<endl;
}
}
使用:
aa*=b();
a->func();
输出:
b::func()
编译期是不调用任何函数的,编译器编译到a->func()时只是检查有没有语法问题,经过检查没有。编译器并不知道调用的是a版本的func()还是b版本的func(),由于a是一个指向b对象的指针,所以a只知道它指向的是一个a类型(或者能转换成a类型)的对象。通常集成体系就说明了(由于是公有继承)b是一种a。在运行期,a要调用a所指向对象的func()函数,就对它指向的对象下达调用func()的命令,结果a所指向的是一个b对象,这个对象就调用了自己版本(b版)的func()函数,所以输出时b::func()
总结:
在编译期决定你应该调用哪个函数的行为是静态绑定(static-binding),这种现象就是静多态。
在运行期决定应该调用哪中类型对象的函数的行为是动态绑定(dynamic-binding),这种现象就是动多态!
注:由于这是我花了有限的时间总结的,语言应用能力比较差,还有比如类模板(静多态和动多态组合的情况)都没有说,最近比较忙,请见谅!
如果还不是很懂,我建议你看c++primer4thedition,讲的比较清晰,但是比较零散!
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯