memset() 初始化类对象
今天看到迅雷2014校招一道笔试题如下:
- #include <iostream>
- using namespace std;
- class parent
- {
- public:
- virtual void output();
- };
- void parent::output()
- {
- printf("parent!");
- }
- class son : public parent
- {
- public:
- virtual void output();
- };
- void son::output()
- {
- printf("son!");
- }
- int main()
- {
- son s;
- memset(&s , 0 , sizeof(s));
- parent& p = s;
- p.output();
- return 0;
- }
输出程序运行结果:程序不输出结果,运行出错!!分析一下原因:
在使用memset初始化对象Obj之前,通过Obj调用Show和Print函数时程序运行正常,但是一旦利用Memset函数初始化该对象,再对该obj调用Show和Print函数,则程序立马崩溃。究其原因是因为初始化obj的时候,将obj包含的指向虚函数表VTBL的指针也清除了。包含虚函数的类对象都有一个指向虚函数表的指针,此指针被用于解决运行时和动态类型强制转换时虚函数的调用问题。该指针是被隐藏的,对程序员来说,这个指针也是不可存取的。当进行memset操作时,这个指针(即指向虚函数表的地址)的值也要被初始化,这样一来,只要一调用虚函数,程序便会崩溃。
这种现象在很多由C转向C++的程序员来说,很容易犯这个错误,而且这个错误很难查。
为了避免这种情况,记住对于有虚拟函数的类对象,决不能使用memset来进行初始化操作。而是要用缺省的构造函数或其它的init例程来初始化成员变量。
当类中有虚函数的时候,编译器会为类插入一个我们看不见的数据并建立一个表。这个表就是虚函数表(vtbl),那个我们看不见的数据就是指向虚函数表的指针——虚表指针(vptr)。虚函数表就是为了保存类中的虚函数的地址。我们可以把虚函数表理解成一个数组,数组中的每个元素存放的就是类中虚函数的地址。当调用虚函数的时候,程序不是像普通函数那样直接跳到函数的代码处,而是先取出vptr即得到虚函数表的地址,根据这个来到虚函数表里,从这个表里取出该函数的地址,最后调用该函数。所以只要不同类的vptr不同,他对应的vtbl就不同,不同的vtbl装着对应类的虚函数地址,这样虚函数就可以完成它的任务了。
合并两家说法
http://blog.csdn.net/huruzun/article/details/28272487
http://blog.csdn.net/lishengwei/article/details/2416847
memset() 初始化类对象相关推荐
- memset初始化类对象出错解析
void *memset(void *s, int v, size_t n); 英文释义如下: Copies the value v (converted to type unsigned char) ...
- c语言 memset 段错误,段错误之memset对类对象的误用
1.问题描述 实际项目中,定义一个如下的基类和子类,均包含有虚函数. //基类 class OriginalTask { public: OriginalTask() {}; virtual ~Ori ...
- 段错误之 memset 对类对象的误用
1.问题描述 实际项目中,定义一个如下的基类和子类,均包含有虚函数. //基类 class OriginalTask { public:OriginalTask() {};virtual ~Origi ...
- python定时重新初始化类_如何重新初始化类对象
我正在制作一个典型的文本游戏程序,我被困在重启功能上.我想重新启动room实例,但是当我试图删除对象时,我得到AttributeError:room1.下面是一些伪代码:class Room: inv ...
- iOS类对象的初始化+initialize
简介 在iOS中,对象可分为类对象和实例对象,实例对象即我们平时alloc init初始化的一个具体的对象,实例对象所属的类,称为类对象.类对象.实例对象 +initialize 是一个类方法,在iO ...
- redis python 出错重连_python穿透类 对象代理
# coding:utf-8 import os import logging # 对象代理 # 用于解决需要在包调用与业务代码之间增加一些其他操作的场景 # 比如:应用程序中使用redis包对象,我 ...
- 【C++】利用构造函数对类对象进行初始化
运行环境:VS2017 一.对象的初始化 每一个对象都应当在它建立之时就有就有确定的内容,否则就会失去对象的意义. class Time {int hour = 0;int min = 0;int s ...
- 初始化列表||类对象作为类成员|| 静态成员
初始化列表 作用: C++提供了初始化列表语法,用来初始化属性 语法:构造函数():属性1(值1),属性2(值2)... {} #include <iostream> using name ...
- python类为什么要初始化_python3类对象需要在init中初始化吗?
我们都知道类需要借助类对象才能使用,类对象的作用是不可缺少的.那么,在我们使用类对象的时候需要注意哪些细节呢?比如,有的小伙伴想知道init中需要初始化吗?这个问题不知道大家都考虑了没有,小编已经查阅 ...
最新文章
- liunx 上get 不到url参数 java_thinkphp5.0 模板上直接获取url参数
- java企业号回调模式,微信公众平台企业号开发—开启回调模式
- 机器学习与流体动力学:谷歌AI利用「ML+TPU」实现流体模拟数量级加速
- 使用最大似然法来求解线性模型(1)
- git下载安装、验证、企业实战单机、多人协作
- mouseup 左键_javascript中mouseup事件丢失的原因与解决办法
- (计算机组成原理)第五章中央处理器-第五节2:指令流水线影响因素和分类及多发技术
- 【搜索】【广搜模板】
- 项目中初试PHP单元测试
- Ubuntu 安装永中Office2009个人版
- 程序员实用小工具(一)
- 看的见的算法——三门问题
- 利用草地湿润模型学习机器学习之参数估计
- Google 微数据,快速指引。
- 为什么程序员喜欢这些键盘?
- codeMirror使用记录
- element中table多选功能禁止选择某一项
- 基于java的心理健康网站的设计与实现_基于JavaEE心理健康教育网站的设计与开发.doc...
- flash在线拍照并上传到后台(servlet)
- ios 使用webview 查找_ios: WebView内高亮搜索
热门文章
- html自动切换文字,JS实现自动切换文字的导航效果代码
- Spring Cloud 之 Ribbon,Spring RestTemplate 调用服务
- Java 算法 面试
- centos7 mysql8 主从_CentOS7开启MySQL8主从备份、每日定时全量备份(推荐)
- ubuntu 安装java_Hadoop3.1.3安装教程_单机/伪分布式配置
- 菜鸟python_手把手教你,菜鸟也能用Python写一个2048游戏
- nodejs 遍历json数据_PostgreSQL 务实应用(四/5)JSON
- flutter-dart
- 跑了10千米,再一次伤了膝盖
- 变态的儿童国学教育与孔子真正的教育之道