今天看到迅雷2014校招一道笔试题如下:

[cpp] view plaincopy
  1. #include <iostream>
  2. using namespace std;
  3. class parent
  4. {
  5. public:
  6. virtual void output();
  7. };
  8. void parent::output()
  9. {
  10. printf("parent!");
  11. }
  12. class son : public parent
  13. {
  14. public:
  15. virtual void output();
  16. };
  17. void son::output()
  18. {
  19. printf("son!");
  20. }
  21. int main()
  22. {
  23. son s;
  24. memset(&s , 0 , sizeof(s));
  25. parent& p = s;
  26. p.output();
  27. return 0;
  28. }

输出程序运行结果:程序不输出结果,运行出错!!分析一下原因:

在使用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() 初始化类对象相关推荐

  1. memset初始化类对象出错解析

    void *memset(void *s, int v, size_t n); 英文释义如下: Copies the value v (converted to type unsigned char) ...

  2. c语言 memset 段错误,段错误之memset对类对象的误用

    1.问题描述 实际项目中,定义一个如下的基类和子类,均包含有虚函数. //基类 class OriginalTask { public: OriginalTask() {}; virtual ~Ori ...

  3. 段错误之 memset 对类对象的误用

    1.问题描述 实际项目中,定义一个如下的基类和子类,均包含有虚函数. //基类 class OriginalTask { public:OriginalTask() {};virtual ~Origi ...

  4. python定时重新初始化类_如何重新初始化类对象

    我正在制作一个典型的文本游戏程序,我被困在重启功能上.我想重新启动room实例,但是当我试图删除对象时,我得到AttributeError:room1.下面是一些伪代码:class Room: inv ...

  5. iOS类对象的初始化+initialize

    简介 在iOS中,对象可分为类对象和实例对象,实例对象即我们平时alloc init初始化的一个具体的对象,实例对象所属的类,称为类对象.类对象.实例对象 +initialize 是一个类方法,在iO ...

  6. redis python 出错重连_python穿透类 对象代理

    # coding:utf-8 import os import logging # 对象代理 # 用于解决需要在包调用与业务代码之间增加一些其他操作的场景 # 比如:应用程序中使用redis包对象,我 ...

  7. 【C++】利用构造函数对类对象进行初始化

    运行环境:VS2017 一.对象的初始化 每一个对象都应当在它建立之时就有就有确定的内容,否则就会失去对象的意义. class Time {int hour = 0;int min = 0;int s ...

  8. 初始化列表||类对象作为类成员|| 静态成员

    初始化列表 作用: C++提供了初始化列表语法,用来初始化属性 语法:构造函数():属性1(值1),属性2(值2)... {} #include <iostream> using name ...

  9. python类为什么要初始化_python3类对象需要在init中初始化吗?

    我们都知道类需要借助类对象才能使用,类对象的作用是不可缺少的.那么,在我们使用类对象的时候需要注意哪些细节呢?比如,有的小伙伴想知道init中需要初始化吗?这个问题不知道大家都考虑了没有,小编已经查阅 ...

最新文章

  1. liunx 上get 不到url参数 java_thinkphp5.0 模板上直接获取url参数
  2. java企业号回调模式,微信公众平台企业号开发—开启回调模式
  3. 机器学习与流体动力学:谷歌AI利用「ML+TPU」实现流体模拟数量级加速
  4. 使用最大似然法来求解线性模型(1)
  5. git下载安装、验证、企业实战单机、多人协作
  6. mouseup 左键_javascript中mouseup事件丢失的原因与解决办法
  7. (计算机组成原理)第五章中央处理器-第五节2:指令流水线影响因素和分类及多发技术
  8. 【搜索】【广搜模板】
  9. 项目中初试PHP单元测试
  10. Ubuntu 安装永中Office2009个人版
  11. 程序员实用小工具(一)
  12. 看的见的算法——三门问题
  13. 利用草地湿润模型学习机器学习之参数估计
  14. Google 微数据,快速指引。
  15. 为什么程序员喜欢这些键盘?
  16. codeMirror使用记录
  17. element中table多选功能禁止选择某一项
  18. 基于java的心理健康网站的设计与实现_基于JavaEE心理健康教育网站的设计与开发.doc...
  19. flash在线拍照并上传到后台(servlet)
  20. ios 使用webview 查找_ios: WebView内高亮搜索

热门文章

  1. html自动切换文字,JS实现自动切换文字的导航效果代码
  2. Spring Cloud 之 Ribbon,Spring RestTemplate 调用服务
  3. Java 算法 面试
  4. centos7 mysql8 主从_CentOS7开启MySQL8主从备份、每日定时全量备份(推荐)
  5. ubuntu 安装java_Hadoop3.1.3安装教程_单机/伪分布式配置
  6. 菜鸟python_手把手教你,菜鸟也能用Python写一个2048游戏
  7. nodejs 遍历json数据_PostgreSQL 务实应用(四/5)JSON
  8. flutter-dart
  9. 跑了10千米,再一次伤了膝盖
  10. 变态的儿童国学教育与孔子真正的教育之道