[java的多态怎么实现]这几天我在重新复习Java语言基础,虽然和团队一起,自己个人都进行了实际项目的开发,但越往上面走越觉得自己应该花点时间看看Java的基础知识,巩固一下基础。今天复习的是多态,同时...+阅读
无关其它,要非这样说,只能归结于c++机制. 虚函数要求函数名一样,其实现多态的本质是:
父类* =new 子类,但如此一来,指针就变成父类的了,delete 指针的时候,由于c++会指针类型来调用析构函数,这样就调不到子类析构,有一解决办法是把该父类指针转成new时的子类指针,这样就会调到子类析构,但很多情况下父类根本就不知道是否有子类,就不能盲目强转,为了解决这一矛盾,就加了析构可以是虚函数,一般用在父类有virtual成员时,其析构必为virtual。
LZ想问的是虚函数要求名字一样,而析构名字根本就不一样怎么可能是虚函数,因为析构是和类名一样的,如果析构名字一样就会出现类重定义了,它是析构名字和虚函数双方妥协而要同时满足多态机制的产物,当然,单从虚函数的角度来看它肯定是不满足的。
C派生类的析构函数是如何工作的
这个要分情况,特别是在多态的时候更要小心
一般情况下就像你说的,先自己析构再基类析构,但是如果你代码中存在多态行为,析构就要看基类的析构函数是否定义成vritual了,如果没有就只调用基类析构,如下:
class A
{
public:
A(){};
~A(){}
};
class B : public A
{
public:
B(){};
~B(){};
};
如果你的代码只是:
B *b = new B; delete b;那是肯定先调B的析构,然后调A的析构
但是如果是这样的多态形式
A *a = new B; delete a; 这个时候的析构只调用了基类A的析构,如果把A的析构函数定义成virtual的,那就会先调B的析构,然后调A的,所以涉及到继承的,最好把父类的析构函数定义成vritual形式
什么情况下类的析构函数应该声明为虚函数?为什么
基类的指针指向派生类对象,并用基类的指针删除派生类对象时。
虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。
如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。
所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
扩展资料
当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。
所以注意如果基类不是虚析构函数的话可能会有以下两点问题:
1、子类所分配的内存不能被释放
2、子类中成员变量类所分配的内存也不能被释放,因为子类析构函数没有被调用,其变量的析构函数肯定也没被调用了
构造函数不能用虚拟,因为用也没用,不管是在栈上构造对象,还是在堆上构造对象,也不管以后是否使用父类的指针或引用来指向或引用这个对象,在构造的那“一瞬间",总归要指明要构造对象的具体类型,所以,对象在构造过程中不存在运行时动态绑定的多态行为。
参考资料来源:百科--虚析构函数
c什么时候不在析构函数里delelete而自己写个Destroy函数实现
这不是C++的规则,是习惯使然。
多态基类,一般都是使用虚析构函数的,这是为了防止内存泄露。你说的定义一个destroy函数来完成某些缓冲区的删除,也是一个方便的方法。毕竟通过虚析构函数来释放某些空间的话,逻辑上有时候会让人感觉有点不太好理解。所以定义一个destroy函数(虚函数),来手动明确的执行空间释放操作,(当然,把这个destroy函数放在基类的析构函数(非虚)里面被调用也可以——这样在继承类析构里面可以不用调用了)。
比如可以这样:
class CBase
{
public:
CBase(){};
~CBase(){ Destroy();}; // 基类析构中调用即可(不在析构中调用,显示调用也可以)。
virtual void Destroy()
{ delete [] pBufferBase;};
char* pBufferBase; // 假设构造时候分配了堆空间
}
class CChild: public CBase
{
public:
CChild(){};
~Child(){};// 这儿可以不调用了,省事
virtual void Destroy()
{
delete [] pBufferChild;
CBase::Destroy(); // 再调用父类的Destroy函数,执行父类成员的缓冲区释放。
}
char* pBufferChild; // 假设构造时候分配了堆空间
}
使用的时候:
CBase * pObject = new CChild;
delete pObject; // 这样使用 ,可以通过F11跟踪观察,就会发现执行过程,先基类析构函数-》子类Destroy函数-》基类Destroy函数。
这样,代码简洁,逻辑清晰。
以下为关联文档:
高手进 java中的多态具体怎样实现。。。呵呵哈、充钻就不必了、我的答案 你先试试看、能不能解决、若不能你加我Q、我帮你! Java中的多态允许父类指针指向子类实例。如:Father obj=new Child();(其中Child是Fathe...
什么是多态多态的概念多态的体现多态的应用多态是一种编程技巧 它增加论了程序的可扩展性 比如你要做个篮子放水果,你当然不希望造这样的篮子--苹果篮子,橘子篮子,梨篮子,正常人都会想,麻烦啊,我就造个篮子,什么都能放,干嘛造...
雅思考试:A类与G类的区别是什么对不少准备报考梧州雅思考试的同学来说,对于雅思中的A类和G类考试可能会搞不清楚区别。以下是出国留学网小编为大家整理的梧州雅思考试A类和G类的区别,更多雅思考试请关注出国...
如何正确调用Create或者CreateEx函数生成CWnd类派生类的具有WSnew 一个CWnd,再Create不就成功了么Create的参数很简单啊,你注意不同的控件,有不同的字符串标示,比如:_T("EDIT") _T("LISTBOX")等,剩下的参数是窗口位置、样式、父窗口、ID,这些都好赋...
雅思口语g类与a类评分标准一样吗A类和G类的评分标准不一样~~具体A类的话:Reading Listening9 40 9 408.5 38.39 8.5 38.398 36.37 8 36.377.5 34.35 7.5 34.357 31.32.33 7 32.336.5 28.29.30 6.5 29.30.316...
基类指针如何访问派生类新增成员函数#include<iostream> using namespace std; class A { public: virtual void show()=0; }; class B:public A { public : void show(){cout<<;"原基类函数"<<endl;}void show_...
派生类指针指向基类对象如何调用其成员函数用:pb->f(); 即可。 类A中有了虚函数就会再类的数据成员的最前面添加一个vfptr指针(void** vfptr),这个指针用来指向一个vtable表 (一个函数指针数组) (一个类只有一个该表),该表存储着...
有一首歌歌词我们不一样不一样不一样歌名是什么 歌曲:我们不一样 演唱: 大壮 收录专辑: 《我们不一样》 发行时间: 2017-06-06 我们不一样 - 大壮 词/曲:高进 编曲:张亮 缩混:侯春阳 这么多年的兄弟 有谁比我更了解你 太多太多不...
c中什么时候调用构造函数和析构函数c中什么时候调用构造函数和析构函数,C类的构造函数调用问题:在对象被创建的时候就会调用构造函数,比如 声明一个类class A{...},当你在main函数中 A a ; 定义一个对象a的时候, 就...