学习整理——C++ virtual虚函数与多态
多态与动态绑定
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
另一个与多态相关的一个名词是动态绑定:动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。程序运行过程中,把函数(或过程)调用与响应调用所需要的代码相结合的过程称为动态绑定。Java是一个纯面向对象的语言,要理解动态绑定,可以简单写一段代码。
-
public
class Poly {
-
public static void main(String[] arg){
-
Animal animal=getAnimal(System.currentTimeMillis());
-
animal.shout();
-
}
-
-
private static Animal getAnimal(long tsp){
-
if(tsp %
2 ==
0){
-
return
new Cat();
-
}
else{
-
return
new Dog();
-
}
-
}
-
}
-
-
abstract
class Animal{
-
abstract public void shout();
-
}
-
-
class Cat extends Animal{
-
@Override
-
public void shout(){
-
System.out.println(
"Miao");
-
}
-
}
-
-
class Dog extends Animal{
-
@Override
-
public void shout(){
-
System.out.println(
"Wang");
-
}
-
}
上述代码中,在编译期我们无法确定main()函数中的animal.shout()会调用的是输出Miao的还是Wang的函数,只有在运行期通过对当前时间戳的判断才会唯一确定,这就是动态绑定。按照这种思路,或许我们很容易将这个Java代码写成C++的代码。
-
#include <iostream>
-
-
using
namespace
std;
-
-
class Animal{
-
public:
-
void shout(){
-
cout <<
"Not implement" <<
endl;
-
}
-
};
-
-
class Cat:
public Animal{
-
public:
-
void shout(){
-
cout <<
"Miao" <<
endl;
-
}
-
};
-
-
class Dog:
public Animal{
-
public:
-
void shout(){
-
cout <<
"Wang" <<
endl;
-
}
-
};
-
-
Animal* getAnimal(int flag){
-
if(flag %
2){
-
return
new Cat();
-
}
else{
-
return
new Dog();
-
}
-
}
-
-
int main(){
-
int flag;
-
cin >> flag;
-
Animal* animal = getAnimal(flag);
-
animal->shout();
-
return
0;
-
}
-
但是,无论输入的flag是多少,输出都会是Not implement。这是因为C++是编译性语言,在编译期,由于声明的animal变量是Animal指针,所以编译器在编译animal->shout()时,直接引用了Animal类的shout()函数,运行时就调用了该函数,输出Not implement。由于Cat和Dog都是继承自Animal,所有两者都会包含Animal的shout()函数,只不过是被重写了而在一般情况下不可见。为了解决这种问题,做到上面Java代码的类似效果,C++引入了virtual关键字,正确的写法是:
-
#include <iostream>
-
-
using
namespace
std;
-
-
class Animal{
-
public:
-
virtual void shout(){
-
cout <<
"Not implement" <<
endl;
-
}
-
virtual ~Animal(){}
-
};
-
-
class Cat:
public Animal{
-
public:
-
void shout(){
-
cout <<
"Miao" <<
endl;
-
}
-
};
-
-
class Dog:
public Animal{
-
public:
-
void shout(){
-
cout <<
"Wang" <<
endl;
-
}
-
};
-
-
Animal* getAnimal(int flag){
-
if(flag %
2){
-
return
new Cat();
-
}
else{
-
return
new Dog();
-
}
-
}
-
-
int main(){
-
int flag;
-
cin >> flag;
-
Animal* animal = getAnimal(flag);
-
animal->shout();
-
return
0;
-
}
-
实现原理
参考自:http://blog.csdn.net/chosen0ne/article/details/10350305
C++
在C++中通过虚函数表的方式实现多态,每个包含虚函数的类都具有一个虚函数表(virtual table),在这个类对象的地址空间的最靠前的位置存有指向虚函数表的指针。在虚函数表中,按照声明顺序依次排列所有的虚函数。实例化一个对象时调用完构造函数后,便会初始化这些指针。由于C++在运行时并不维护类型信息,所以在编译时直接在子类的虚函数表中将被子类重写的方法替换掉。当程序中将要调用一个虚函数时,编译器会编译成从指针中找到具体的实现函数。因为虚函数指针在对象实例化时就被初始化了,所以即便是该对象被一个父类指针指向也能找到正确的函数。
另外,一日为虚终生为虚。一个函数被声明为虚时,其衍生类的该函数也将一直是虚函数,即使衍生类没有显式声明为virtual。
Java
而Java中,在运行时会维持类型信息以及类的继承体系。每一个类会在方法区中对应一个数据结构用于存放类的信息,可以通过Class对象访问这个数据结构。其中,类型信息具有superclass属性指示了其超类,以及这个类对应的方法表(其中只包含这个类定义的方法,不包括从超类继承来的)。而每一个在堆上创建的对象,都具有一个指向方法区类型信息数据结构的指针,通过这个指针可以确定对象的类型。
JVM中用于方法调用的指令包括:
invokevirtual:用于调用实例方法,会根据对象的实际类型进行调用。
invokespecial:需要特殊处理的实例方法,比如:public final方法、私有方法和父类方法等。调用的方法取决于引用的类型。
invokeinterface:调用接口的方法。
invokestatic:调用类方法。
按照上面描述,对于子类覆盖父类的方法,编译后,调用指令应该是invokevirtual,调用的方法取决于对象的类型。invokevirtual方法查找的实现方式是:
1. 通过对象中类指针找到其类信息,然后在方法表中根据方法签名找到该方法。
2. 如果不在当前类,则递归查找其父类的方法表直到Object类。
3. 如果找到Object类,也没有该方法,会抛出NoSuchMethodException异常。
与js、lua等动态语言类似,Java多态的实现方式依赖于内存中的类型体系信息,存在一个“原型链”,是一个完全动态的查找过程,相对于C++而言,效率会低一些,因为存在一个链表遍历查找的过程。之所以,Java中可以这样实现,本质上是因为它是一门虚拟机语言,虚拟机会维持所有的这些类型信息。
纯虚函数
虚函数为C++提供实现动态绑定的机制,但是拥有虚函数的类本身是可以被实例化的。要实现类似Java抽象类的机制,即类本身不能实例化,其子类需要实现其所有抽象方法才能被实例化,C++提供了纯虚函数。在C++中,拥有纯虚函数的类不能被实例化,其子类也需要实现其所有纯虚函数才能被实例化。纯虚函数的写法是:
-
virtual void shout()=
0;
//纯虚函数
-
virtual void toShout(){};
//虚函数
只拥有纯虚函数可以被用作接口来使用,提供给其衍生类才实现,类似Java的interface。
问题
1.构造函数中可以调用虚函数吗?析构函数中可以调用虚函数吗?
如果在父类构造函数中调用虚函数,由于子类还没构造,所以可能会出错,但由于C++避免这种错误,所以会调用父类的实现,但这不是多态;在子类中调用虚函数,由于子类已经构造了,此时调用虚函数跟普通方法没有任何区别。
如果在子类析构函数中调用虚函数,情况如上,和调用普通方法没有任何区别;而在父类析构函数中调用虚函数,如果只是虚函数,情况也如上,C++会调用父类的实现,但如果是纯虚函数,编译期编译器就会报错,出现undefined reference。
所以不要在构造函数和析构函数里调用虚函数,即使没有语法错误,运行也不会如你所愿,就算有时会成功(不同编译器),到最后也会让人困惑不已。这种调用根本不是起到虚函数的作用,所以为了代码规范,可以说成是不可以调用。
2.构造函数可以是虚函数吗?
不可以。虚函数指针是存放在对象内存中,一个对象在实例化(构造)前是没有内存的。如果构造函数都是虚的时候,该虚构造函数指针能够放在哪里?该问题编译器能够查看出来,是语法错误。
3.析构函数可以是虚函数吗?
当一个类拥有虚函数的时候,析构函数应当也被声明为virtual。因为当使用多态时,父类的析构函数没有声明为virtual而调用delete时,会直接调用父类析构函数,子类没有被调用。为了程序的正确运行,防止只析构基类而不析构派生类的状况发生,应当记住这个规范。
<div class="recommend-box"><div class="recommend-item-box type_blog clearfix" data-report-click="{"mod":"popu_614","dest":"https://blog.csdn.net/weixin_30953735/article/details/82633999","strategy":"BlogCommendFromMachineLearnPai2","index":"0"}">
<div class="content" style="width: 712px;">
<a href="https://blog.csdn.net/weixin_30953735/article/details/82633999" target="_blank" rel="noopener" title="C++中为什么析构函数是虚函数">
<h4 class="text-truncate oneline" style="width: 552px;">
<em>C</em>++中为什么析构<em>函数</em>是<em>虚</em><em>函数</em> </h4>
<div class="info-box d-flex align-content-center">
<p class="date-and-readNum oneline">
<span class="date hover-show">09-11</span>
<span class="read-num hover-hide">
阅读数
2986</span>
</p>
</div>
</a>
<p class="content" style="width: 712px;">
<a href="https://blog.csdn.net/weixin_30953735/article/details/82633999" target="_blank" rel="noopener" title="C++中为什么析构函数是虚函数">
<span class="desc oneline">如果基类的析构函数不是虚函数,在特定情况下会导致派生来无法被析构。情况1:用派生类类型指针绑定派生类实例,析构的时候,不管基类析构函数是不是虚函数,都会正常析构情况2:用基类类型指针绑定派生类实例,析...</span>
</a>
<span class="blog_title_box oneline ">
<span class="type-show type-show-blog type-show-after">博文</span>
<a target="_blank" rel="noopener" href="https://blog.csdn.net/weixin_30953735">来自: <span class="blog_title"> weixin_30953735的博客</span></a>
</span>
</p>
</div>
</div>
析构函数是否必须为虚函数?什么情况下才应该定义析构函数为虚函数?
07-07 阅读数 5373
多态是面向对象的一个基本属性,包括静态多态(编译阶段)和动态多态(运行阶段),静态多态主要是指函数参数不同产生的多态性,是在编译阶段可以识别的一种多态机制,而运行时多态则主要用于基类指针指向派生类对象... 博文 来自: zhangqk2016的博客
什么情况下析构函数需要定义为虚函数?
09-26 阅读数 1295
一、什么情况下析构函数需要定义为虚函数?答案是在实现多态时。如果单单是填空题,相信大家都可以拿满分。但说到何谓之多态,可能大家的回答不尽相同。至于多态时怎样实现的?又有什么样的作用呢?这样深入逼问下去... 博文 来自: syeming的编程专栏
C++多态--虚函数virtual及override
09-14 阅读数 197
https://blog.csdn.net/i_chaoren/article/details/77281785C++多态C++多态(polymorphism)是通过虚函数来实现的,虚函数允许子类重新... 博文 来自: chengde6896383的专栏
<div class="recommend-item-box recommend-recommend-box"><div id="kp_box_59" data-pid="59"><script type="text/javascript">
(function() {
var s = "_" + Math.random().toString(36).slice(2);
document.write('<div style="" id="' + s + '"></div>');
(window.slotbydup = window.slotbydup || []).push({
id: "u3491668",
container: s
});
})();
析构函数为什么要是虚函数
02-25 阅读数 2194
原因:基类对象的指针操作派生类对象时,防止析构函数只调用基类的,而不调用派生类的 下面详细说明://基类classA{public:A(){cout"A构造函数"endl;}~A(){cout"A被销... 博文 来自: 碎碎絮語
C++ Virtual 完美诠释
03-13 阅读数 1546
解答了我的一些疑问,觉得写的不错!!!转载一下。virtual在英文中表示“虚”、“虚拟”的含义。c++中的关键字“virtual”主要用在两个方面:虚函数与虚基类。下面将分别从这两个方面对virtu... 博文 来自: 让一切变得简单
C++中virtual的三种用法
02-27 阅读数 1万+
virtual用法一:#include&lt;iostream&gt;usingnamespacestd;classA{public:virtualvoiddisplay(){cout... 博文 来自: jirryzhang的博客
C++ virtual
08-28 阅读数 69
1.什么是virtualvirtual是一个C++的修饰符,用于修饰函数,被修饰的函数称为虚函数。2.为什么需要?在C++中,我们都知道要实现多态有2种方法,一种是重写,一种是重载,重载是横向的,意思... 博文 来自: fbher的博客
C++中virtual关键字的用法
02-10 阅读数 1万+
关于virtual关键字的用法总结如下,有错误或者总结不到位的情况请能帮本人指出,非常感谢!Virtual是C++OO机制中很重要的一个关键字。只要是学过C++的人都知道在类Base中加了Virtua... 博文 来自: 一缕阳光的博客
<div class="recommend-item-box recommend-recommend-box"><div id="kp_box_60" data-pid="60"><div class="mediav_ad"><newsfeed class="newsfeed QIHOO__WEB__SO__1570432062447_180" id="QIHOO__WEB__SO__1570432062447_180" style="display:block;margin:0;padding:0;border:none;width:900px;height:84px;overflow-y:hidden;overflow-x:hidden;position:relative;text-align:left;"><info-div id="QIHOO__WEB__SO__1570432062447_180-info" style="zoom:1"><info-div class="QIHOO__WEB__SO__1570432062447_180 singleImage clk" data-href="https://s3.nzbdw.com/s?type=2&r=20&mv_ref=blog.csdn.net&enup=CAABcVhjKAgAAihjWHEA&mvid=MTA1NzY4MTQ2MTQzMjE1MDcwMTAwMTk&bid=13a3b52f97dae909&price=AAAAAF2a5D4AAAAAAACnmryGcRiEm6sN+4e6hg==&finfo=DAABCAABAAAArggAAgAAAFoEAAM/QVqAsRVFPQAIAAIAAAADCgADBMQiM98n9KUIAAQAAAFIBgAGLbcGAAoAAAYADD9cCAAOAAAAOwoADwAAAAAAGozgAA&ugi=FcTgigEVyNtrTBUCFUAVXhUAABXd++NNFoAIFcgBFoCumNOWk8oFHBasl8yH4cX49cEBFQAAAA&uai=FeTGlAIlAhUEFuzJ88XXxozECRXyCCXmk+64AiUAFRoUABwW9arHmsePhtC0ARUAAAA&ubi=Fcb8SxXo7O0CFYjB8RgVuvXXXBUEFRwWgtKsiBcW7MmIreGMkcQJNAIWqOCQgAglBhWZwoiWCRWmARUANpC8tNXJsYCR6AEA&clickid=0&cpx=__OFFSET_X__&cpy=__OFFSET_Y__&cs=__EVENT_TIME_START__&ce=__EVENT_TIME_END__&adsw=__ADSPACE_W__&adsh=__ADSPACE_H__&csign2=qQaNPZX6fvo=&url=http%3A%2F%2Fsx1.aihuaiedu.cn%2Fhh360%2Fpc%2Fzs%2Fa12%2F%3Fll-zs-sz-H0201" data-pv="https://s3.nzbdw.com/s?type=1&r=20&tid=MTA1NzY4MTQ2MTQzMjE1MDcwMTAwMTk&finfo=DAABCAABAAAArggAAgAAAFoEAAM/QVqAsRVFPQAIAAIAAAADCgADBMQiM98n9KUIAAQAAAFIBgAGLbcGAAoAAAYADD9cCAAOAAAAOwoADwAAAAAAGozgAA&mv_ref=blog.csdn.net&enup=CAABcVhjKAgAAihjWHEA&mvid=MTA1NzY4MTQ2MTQzMjE1MDcwMTAwMTk&bid=13a3b52f97dae909&ugi=FcTgigEVyNtrTBUCFUAVXhUAABXd++NNFoAIFcgBFoCumNOWk8oFHBasl8yH4cX49cEBFQAAAA&uai=FeTGlAIlAhUEFuzJ88XXxozECRXyCCXmk+64AiUAFRoUABwW9arHmsePhtC0ARUAAAA&ubi=Fcb8SxXo7O0CFYjB8RgVuvXXXBUEFRwWgtKsiBcW7MmIreGMkcQJNAIWqOCQgAglBhWZwoiWCRWmARUANpC8tNXJsYCR6AEA&ds=1&price=AAAAAF2a5D4AAAAAAACnmryGcRiEm6sN+4e6hg==,https://max-l.mediav.com/rtb?type=2&ver=1&v=CGQSEDEzYTNiNTJmOTdkYWU5MDkYsqOKASCisEUoAWIXMTA1NzY4MTQ2MTQzMjE1MDcwMTAwMTmIAQA&k=gRiA6AAAAAA=&w=AAAAAF2a5D4AAAAAAACnytO0op3zRNhf7bXs_A&i=bOahTbleyDZQ&exp=BQBECQFEAQJECQBEEABDJQBD&z=1" data-clk="https://max-l.mediav.com/rtb?type=3&ver=1&v=CGQSEDEzYTNiNTJmOTdkYWU5MDkYsqOKASCisEUoAWIXMTA1NzY4MTQ2MTQzMjE1MDcwMTAwMTlwAA&k=1rZcRwAAAAA=&i=bOahTbleyDZQ&exp=BQBECQFEAQJECQBEEABDJQBD&x=__OFFSET_X__&y=__OFFSET_Y__&st=__EVENT_TIME_START__&et=__EVENT_TIME_END__&adw=__ADSPACE_W__&adh=__ADSPACE_H__&tc=&turl=">
<info-div class="wrap">
<info-div class="singleImage-img singleImage-img-left">
<info-div class="img" style="background-image:url(https://s3m.nzwgs.com/galileo/622371-1e05d9904067e76a09c88c78ca286dcc.jpg)"><info-div class="ads-tag"></info-div></info-div>
</info-div>
<info-div class="singleImage-body singleImage-body-left">
<info-div class="singleImage-title">10月起,深圳有一种学历叫免考本科,一年课程,毕业即正规本科</info-div>
<info-div class="singleImage-desc">爱华学历中心 · 猎媒</info-div>
</info-div>
C++ Virtual详解
08-23 阅读数 295
C++Virtual详解Virtual是C++OO机制中很重要的一个关键字。只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派... 博文 来自: Huangrg的专栏
<div class="recommend-item-box blog-expert-recommend-box" style="display: block;">
<div class="d-flex">
<div class="blog-expert-recommend">
<div class="blog-expert">
<div class="blog-expert-flexbox" data-report-view="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/weixin_30953735" target="_blank"><img src="https://avatar.csdn.net/2/5/5/3_weixin_30953735.jpg" alt="花岗岩先生" title="花岗岩先生"></a><span data-report-click="{"mod":"popu_710","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><span class="blog-expert-button-follow btn-red-follow" data-name="weixin_30953735" data-nick="花岗岩先生">关注</span></span></div><div class="info"><span data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/weixin_30953735" target="_blank"><h5 class="oneline" title="花岗岩先生">花岗岩先生</h5></a></span> <p></p><p class="article-num" title="20篇文章"> 20篇文章</p><p class="article-num" title="排名:千里之外"> 排名:千里之外</p><p></p></div></div></div><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/zhangqk2016" target="_blank"><img src="https://avatar.csdn.net/4/7/C/3_zhangqk2016.jpg" alt="zhangqk2016" title="zhangqk2016"></a><span data-report-click="{"mod":"popu_710","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><span class="blog-expert-button-follow btn-red-follow" data-name="zhangqk2016" data-nick="zhangqk2016">关注</span></span></div><div class="info"><span data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/zhangqk2016" target="_blank"><h5 class="oneline" title="zhangqk2016">zhangqk2016</h5></a></span> <p></p><p class="article-num" title="2篇文章"> 2篇文章</p><p class="article-num" title="排名:千里之外"> 排名:千里之外</p><p></p></div></div></div><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/simon_2011" target="_blank"><img src="https://avatar.csdn.net/E/9/8/3_simon_2011.jpg" alt="simon_syeming" title="simon_syeming"></a><span data-report-click="{"mod":"popu_710","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><span class="blog-expert-button-follow btn-red-follow" data-name="simon_2011" data-nick="simon_syeming">关注</span></span></div><div class="info"><span data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/simon_2011" target="_blank"><h5 class="oneline" title="simon_syeming">simon_syeming</h5></a></span> <p></p><p class="article-num" title="24篇文章"> 24篇文章</p><p class="article-num" title="排名:千里之外"> 排名:千里之外</p><p></p></div></div></div><div class="blog-expert-item"><div class="blog-expert-info-box"><div class="blog-expert-img-box" data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/chengde6896383" target="_blank"><img src="https://avatar.csdn.net/4/6/2/3_chengde6896383.jpg" alt="AndyCheng_hgcc" title="AndyCheng_hgcc"></a><span data-report-click="{"mod":"popu_710","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><span class="blog-expert-button-follow btn-red-follow" data-name="chengde6896383" data-nick="AndyCheng_hgcc">关注</span></span></div><div class="info"><span data-report-click="{"mod":"popu_709","dest":"https://blog.csdn.net/Jeffery_Gong/article/details/52749587"}"><a href="https://blog.csdn.net/chengde6896383" target="_blank"><h5 class="oneline" title="AndyCheng_hgcc">AndyCheng_hgcc</h5></a></span> <p></p><p class="article-num" title="816篇文章"> 816篇文章</p><p class="article-num" title="排名:6000+"> 排名:6000+</p><p></p></div></div></div></div>
</div>
</div>
</div>
</div><div class="recommend-item-box baiduSearch recommend-box-ident" data-report-view="{"mod":"popu_614","dest":"https://blog.csdn.net/i_chaoren/article/details/77281785","strategy":"searchFromBaidu1","index":"5"}" data-report-click="{"mod":"popu_614","dest":"https://blog.csdn.net/i_chaoren/article/details/77281785","strategy":"searchFromBaidu1","index":"5"}" data-track-view="{"mod":"popu_614","dest":"https://blog.csdn.net/i_chaoren/article/details/77281785","strategy":"searchFromBaidu1","index":4,"extend1":"_"}" data-track-click="{"mod":"popu_614","dest":"https://blog.csdn.net/i_chaoren/article/details/77281785","strategy":"searchFromBaidu1","index":4,"extend1":"_"}" data-flg="true"> <a href="https://blog.csdn.net/i_chaoren/article/details/77281785" target="_blank"> <h4 class="text-truncate oneline" style="width: 633px;"><em>C</em>++<em>多态</em>--<em>虚</em><em>函数</em><em>virtual</em>及override - <em>学习</em>使我快乐 - <em>C</em>SDN博客</h4> <div class="info-box d-flex align-content-center"> <p> <span class="date">10-4</span> </p> </div> </a> </div><div class="recommend-item-box baiduSearch recommend-box-ident" data-report-view="{"mod":"popu_614","dest":"https://blog.csdn.net/xuzhan666/article/details/80797890","strategy":"searchFromBaidu1","index":"6"}" data-report-click="{"mod":"popu_614","dest":"https://blog.csdn.net/xuzhan666/article/details/80797890","strategy":"searchFromBaidu1","index":"6"}" data-track-view="{"mod":"popu_614","dest":"https://blog.csdn.net/xuzhan666/article/details/80797890","strategy":"searchFromBaidu1","index":5,"extend1":"_"}" data-track-click="{"mod":"popu_614","dest":"https://blog.csdn.net/xuzhan666/article/details/80797890","strategy":"searchFromBaidu1","index":5,"extend1":"_"}" data-flg="true"> <a href="https://blog.csdn.net/xuzhan666/article/details/80797890" target="_blank"> <h4 class="text-truncate oneline" style="width: 624px;"><em>C</em>++<em>虚</em><em>函数</em>与<em>多态</em>总结 - xuzhan666的博客 - <em>C</em>SDN博客</h4> <div class="info-box d-flex align-content-center"> <p> <span class="date">11-25</span> </p> </div> </a> </div>
析构函数可以是虚函数吗?
03-13 阅读数 210
在多态的时候,比如基类的指针指向派生类的对象,如果删除该指针delete[]p,就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。如果析构... 博文 来自: qq_29823093的博客
析构函数定义为虚函数
10-24 阅读数 7686
析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调... 博文 来自: alane1986的专栏
<div class="recommend-item-box recommend-recommend-box"><div id="kp_box_61" data-pid="61"><div id="_y8w3wu4929zwx08b2jk5u3di" style="width: 100%;"><iframe width="852" frameborder="0" height="66" scrolling="no" src="https://pos.baidu.com/s?hei=66&wid=852&di=u3600846&ltu=https%3A%2F%2Fblog.csdn.net%2FJeffery_Gong%2Farticle%2Fdetails%2F52749587&psi=c189395cc7ca7b5d01ff29d9bf8beaa0&par=1600x870&cja=false&cec=UTF-8&dc=3&cfv=0&drs=1&cce=true&cpl=21&ari=2&pcs=1759x834&ltr=https%3A%2F%2Fblog.csdn.net%2FJeffery_Gong%2Farticle%2Fdetails%2F52749587&ccd=24&prot=2&dis=0&ps=6812x530&ti=%E5%AD%A6%E4%B9%A0%E6%95%B4%E7%90%86%E2%80%94%E2%80%94C%2B%2B%20virtual%E8%99%9A%E5%87%BD%E6%95%B0%E4%B8%8E%E5%A4%9A%E6%80%81&tcn=1570432063&chi=1&ant=0&pss=1758x8706&tpr=1570432062709&psr=1600x900&cmi=25&pis=-1x-1&cdo=-1&exps=111000,110011&tlm=1570432062&dtm=HTML_POST&dri=0&dai=5&col=zh-CN"></iframe><em style="width:0px;height:0px;"></em></div><script type="text/javascript" src="//rabc1.iteye.com/common/web/production/79m9.js?f=aszggcwz"></script><img class="pre-img-lasy" data-src="https://kunyu.csdn.net/1.png?p=61&a=622&c=0&k=&d=1&t=3&u=24786462e62a47429b51e56900833cb6"></div></div><div class="recommend-item-box baiduSearch recommend-box-ident" data-report-view="{"mod":"popu_614","dest":"https://blog.csdn.net/HardessGod/article/details/81284407","strategy":"searchFromBaidu1","index":"9"}" data-report-click="{"mod":"popu_614","dest":"https://blog.csdn.net/HardessGod/article/details/81284407","strategy":"searchFromBaidu1","index":"9"}" data-track-view="{"mod":"popu_614","dest":"https://blog.csdn.net/HardessGod/article/details/81284407","strategy":"searchFromBaidu1","index":8,"extend1":"_"}" data-track-click="{"mod":"popu_614","dest":"https://blog.csdn.net/HardessGod/article/details/81284407","strategy":"searchFromBaidu1","index":8,"extend1":"_"}" data-flg="true"> <a href="https://blog.csdn.net/HardessGod/article/details/81284407" target="_blank"> <h4 class="text-truncate oneline" style="width: 633px;"><em>c</em>++ 深入理解<em>虚</em><em>函数</em>和<em>多态</em>原理 - HardessGod的博客 - <em>C</em>SDN博客</h4> <div class="info-box d-flex align-content-center"> <p> <span class="date">10-5</span> </p> </div> </a> </div><div class="recommend-item-box baiduSearch recommend-box-ident" data-report-view="{"mod":"popu_614","dest":"https://blog.csdn.net/qq_41661919/article/details/80789708","strategy":"searchFromBaidu1","index":"10"}" data-report-click="{"mod":"popu_614","dest":"https://blog.csdn.net/qq_41661919/article/details/80789708","strategy":"searchFromBaidu1","index":"10"}" data-track-view="{"mod":"popu_614","dest":"https://blog.csdn.net/qq_41661919/article/details/80789708","strategy":"searchFromBaidu1","index":9,"extend1":"_"}" data-track-click="{"mod":"popu_614","dest":"https://blog.csdn.net/qq_41661919/article/details/80789708","strategy":"searchFromBaidu1","index":9,"extend1":"_"}" data-flg="true"> <a href="https://blog.csdn.net/qq_41661919/article/details/80789708" target="_blank"> <h4 class="text-truncate oneline" style="width: 633px;"><em>C</em>++课程笔记——<em>虚</em><em>函数</em>与<em>多态</em> - <em>C</em>SDN博客</h4> <div class="info-box d-flex align-content-center"> <p> <span class="date">6-24</span> </p> </div> </a> </div>
C++ 之 【virtual小结】- 虚函数虚继承
06-04 阅读数 416
C++virtual小结 被virtual修饰的分为两类:虚函数和虚继承一:虚函数当函数被virtual关键字修饰时,该函数被称为虚函数,MSDN上解释如下: 虚函数是指一个类中你希望重载的成员函... 博文 来自: wjydym的博客
C++ 多态和虚函数
08-16 阅读数 1720
一.先搞清overrideoverloadoverwrite的区别1.overload(重载)(不是多态)在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,但参数不同(包括类型、顺序不同... 博文 来自: SJLin
C++中为什么构造函数不能定义为虚函数
01-09 阅读数 9754
关于C++为什么不支持虚拟构造函数,Bjarne很早以前就在C++StyleandTechniqueFAQ里面做过回答Avirtualcallisamechanismtogetworkdonegive... 博文 来自: shilikun841122的博客
C++virtual小结
08-09 阅读数 41
C++virtual小结当函数被virtual关键字修饰时,该函数被称为虚函数,MSDN上解释如下: 虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用... 博文 来自: qq_38970287的博客
<div class="recommend-item-box recommend-recommend-box"><div id="kp_box_62" data-pid="62"><script type="text/javascript">
(function() {
var s = "_" + Math.random().toString(36).slice(2);
document.write('<div style="" id="' + s + '"></div>');
(window.slotbydup = window.slotbydup || []).push({
id: "u3600849",
container: s
});
})();
c++中virtual作用
刚开始看virtual关键字,对于这个东西理解的也不太透彻,virtual关键字我的理解就是一个指向子类的基类指针dad *a =new son(),如果在dad类方法里使用了virtual关键字定义 论坛
C++中析构函数为虚函数
04-12 阅读数 399
1、析构函数是否定义为虚函数的区别(1)析构函数定义为虚函数时:基类指针可以指向派生类的对象(多态性),如果删除该指针delete[]p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调... 博文 来自: king_weng的博客
C++ virtual问题
#include <iostream> #include <string> #include <sstream> using namespace std; class Highlight { publ 论坛
C++中的virtual关键字
09-26 阅读数 578
虚函数与运行多态多态:多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。先看最简... 博文 来自: ZeroZone零域的博客
<div class="recommend-item-box recommend-recommend-box"><div id="kp_box_63" data-pid="63"><script type="text/javascript">
(function() {
var s = "_" + Math.random().toString(36).slice(2);
document.write('<div style="" id="' + s + '"></div>');
(window.slotbydup = window.slotbydup || []).push({
id: "u4221910",
container: s
});
})();
c++: C++ Virtual详解
04-11 阅读数 154
Virtual是C++OO机制中很重要的一个关键字。如下所示:只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如下面例子中的函数print),于是在Base的派生... 博文 来自: DinnerHowe的博客
C++:构造函数和析构函数能否为虚函数
11-06 阅读数 1万+
C++:构造函数和析构函数能否为虚函数?简单回答是:构造函数不能为虚函数,而析构函数可以且常常是虚函数。(1)构造函数不能为虚函数让我们来看看大牛C++之父BjarneStroustrup在《TheC... 博文 来自: xhz1234的专栏
C++中继承及virtual小结
04-04 阅读数 3206
一、继承基础知识C++中的继承1.1继承的基本概念类与类之间的关系has-A,包含关系,用以描述一个类由多个“部件类”构成,实现has-A关系用类的成员属性表示,即一个类的成员属性是另一个已经定义好的... 博文 来自: sinat_27652257的博客
<div class="recommend-item-box recommend-recommend-box"><div id="kp_box_64" data-pid="64"><script type="text/javascript">
(function() {
var s = "_" + Math.random().toString(36).slice(2);
document.write('<div style="" id="' + s + '"></div>');
(window.slotbydup = window.slotbydup || []).push({
id: "u3600856",
container: s
});
})();
浅析c++中virtual关键字
05-25 阅读数 2万+
1.virtual关键字主要是什么作用?c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用。由此可见,virtual主要主要... 博文 来自: djh512的专栏
<div class="recommend-item-box recommend-recommend-box"><div id="kp_box_65" data-pid="65"><script type="text/javascript">
(function() {
var s = "_" + Math.random().toString(36).slice(2);
document.write('<div style="" id="' + s + '"></div>');
(window.slotbydup = window.slotbydup || []).push({
id: "u4221803",
container: s
});
})();
为什么析构函数可以为虚函数,构造函数不能为虚函数?
08-20 阅读数 430
虚函数采用一种虚调用的方法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果创建一个对象,必须要准确知道对象的准确类型,因此构造函... 博文 来自: 找个特立不独行的名的博客
析构函数已经是虚函数了,为什么还会调用基类的析构函数?
struct B{ virtual ~B(){cout<<"B dtor"<<endl;} }; struct D:B{ ~D(){cout<<"D dtor"<<endl;} }; int mai 论坛
C++ Virtual详解
05-11 阅读数 5万+
Virtual是C++OO机制中很重要的一个关键字。只要是学过C++的人都知道在类Base中加了Virtual关键字的函数就是虚拟函数(例如下面例子中的函数print),于是在Base的派生类Deri... 博文 来自: 悦峰原创博客
<div class="recommend-item-box type_hot_word">
<div class="content clearfix" style="width: 712px;">
<div class="float-left">
<span>
<a href="https://www.csdn.net/gather_19/MtTaAg0sMi1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c#siki第五季</a>
</span>
<span>
<a href="https://www.csdn.net/gather_11/MtTaAg0sNC1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c#入门推荐书</a>
</span>
<span>
<a href="https://www.csdn.net/gather_11/MtTaAg0sNi1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c# 解码海康数据流</a>
</span>
<span>
<a href="https://www.csdn.net/gather_12/MtTaAg0sNy1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c# xml的遍历循环</a>
</span>
<span>
<a href="https://www.csdn.net/gather_17/MtTaAg0sOC1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c# 取 查看源码没有的</a>
</span>
<span>
<a href="https://www.csdn.net/gather_15/MtTaAg0sOS1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c#解决高并发 委托</a>
</span>
<span>
<a href="https://www.csdn.net/gather_15/MtTaAg1sMC1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c#日期转化为字符串</a>
</span>
<span>
<a href="https://www.csdn.net/gather_14/MtTaAg1sMS1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c# 显示问号</a>
</span>
<span>
<a href="https://www.csdn.net/gather_1f/MtTaAg1sMi1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c# 字典对象池</a>
</span>
<span>
<a href="https://www.csdn.net/gather_1d/MtTaAg1sNC1kb3dubG9hZAO0O0OO0O0O.html" target="_blank">
c#5.0 安装程序</a>
</span>
</div>
</div>
</div>
<div class="recommend-loading-box">
<img src="https://csdnimg.cn/release/phoenix/images/feedLoading.gif">
</div>
<div class="recommend-end-box" style="display: block;">
<p class="text-center">没有更多推荐了,<a href="https://blog.csdn.net/" class="c-blue c-blue-hover c-blue-focus">返回首页</a></p>
</div>
</div>
<div class="template-box">
<span>©️2019 CSDN</span><span class="point"></span>
<span>皮肤主题: <a href="https://blog.csdn.net/weixin_40515248" target="_blank" style="color:#3399ea">skin-yellow</a></span>
<span> 设计师:
CSDN官方博客 </span>
</div>
<div id="reward" class="reward-box" style="top: 0px; left: -378px;">
<p class="rewad-title">打赏<span class="reward-close"><svg t="1567152543821" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10924" xmlns:xlink="http://www.w3.org/1999/xlink" width="12" height="12"><defs><style type="text/css"></style></defs><path d="M512 438.378667L806.506667 143.893333a52.032 52.032 0 1 1 73.6 73.621334L585.621333 512l294.485334 294.485333a52.074667 52.074667 0 0 1-73.6 73.642667L512 585.621333 217.514667 880.128a52.053333 52.053333 0 1 1-73.621334-73.642667L438.378667 512 143.893333 217.514667a52.053333 52.053333 0 1 1 73.621334-73.621334L512 438.378667z" fill="" p-id="10925"></path></svg></span></p>
<dl>
<dd><a href="javascript:;"><img src="https://avatar.csdn.net/9/F/D/3_jeffery_gong.jpg" alt=""></a></dd>
<dt>
<p class="blog-name">Jeffery_Gong</p>
<p class="blog-discript">“你的鼓励将是我创作的最大动力”</p>
</dt>
</dl>
<div class="money-box">
<span class="choosed choose_money" data-id="5">5C币</span>
<span class="choose_money" data-id="10">10C币</span>
<span class="choose_money" data-id="20">20C币</span>
<span class="choose_money" data-id="50">50C币</span>
<span class="choose_money" data-id="100">100C币</span>
<span class="choose_money" data-id="200">200C币</span>
</div>
<div class="sure-box">
<p class="is-have-money"><a class="reward-sure">确定</a></p>
</div>
</main>