继承类重写虚函数未被成功调用导致的内存访问冲突问题以及解决方法

 这是我遇到的错误,似乎和标题中说的原因相差甚远,不过遇到这种可以编译成功,运行出现Assertion Fail!的错误是最恶心也最痛苦的事情了。

 

 

可以看出对象可能调用析构函数提前释放了内存空间,也就是说这个对象已经不存在了,所以报错内存访问冲突,又或许是当前对象在内存中已经被未知因素销毁,或者这个对象压根就没有被创建过。

在报错点之前设置断点,查看调试信息,找出了错误原因在于下图的函数OnActivateView()没有被调用,从而导致了this对象没有被赋值给ptr_View,因此导致ptr_View是空指针,因此访问他指向的对象当然就会出现内存访问冲突,因为需要访问的那块内存不属于这个程序,它由操作系统管理着,当访问到了非法的内存,自然就会报出这种错误了!!!

 

 

解决方法:

百度上并没有过类似的像我这样的问题(我很肯定,因为我实在是找遍了,就差没上google了),论坛也没有相关的话题讨论,反反复复改了很久很久也没成功,开始怀疑到底是不是这个问题了。

不过还好没放弃,各种方法都试了一下,总算试出来了一种方法(如下图),因为这个类继承于CScrollView,而CScrollView又继承于CView,刚刚的那个OnActivateView()函数是重载的父类CScrollView的虚函数,不过值得注意的是这个父类(CScrollView)也是继承于它的父类的(CView -- 最终基类),因此我试了一下将OnActivateView()的参数全部改成CView,这样一般都不会报错,并且兼容性也会更高(当时我就只是简单的这样想的),结果居然就成功了!!!!!!!!

现在回想起来都觉得莫名其妙,改一下重载的父类的虚函数的参数就行了。   不过反推一下,想想这个错误的症结估计就在于:

CScrollView的OnActivateView()继承于CView,而OnActivateView()的实现估计只有CView实现了(个人猜测,后面会有个人的看法),而他的所有子类都没有实现。

如果他的子类想要成功调用OnActivateView()的话,只能够调用父类的这一函数(可知CView中的OnActivateView并非纯虚函数)。

这样的设计模式大概就是因为所有的子类确实是可以共用这一函数,而不需要各自实现,并非因为子类的不同而使OnActivateView的功能出现差异,就好像一个java的接口那样。

因此,我这里需要成功调用OnActivateView()这一函数的话,参数就必须是CView类型,而不能够是CScrollView类型,因为这里的数据类型只能向下兼容,不能向上兼容。

因此 我之前把参数类型写成CScrollView类型,自然是不会报错了,因为我继承的父类确实是有这个虚函数的声明的,但是没有对其进行实现(就好像是实现了一个空的构造函数一样),自然不会调用成功了。

 

原文地址:https://www.cnblogs.com/xwmcc/p/10030934.html