class point
{
public:
point():x(0),y(0),z(0){}
point(int xx,int yy,int zz):x(xx),y(yy),z(zz){}
virtual ~point(){}
virtual int func(){return y+x+z;}
protected:
int x;
int y;
int z;
};point pt(10,20,30);
memset(&pt,0,sizeof(point));
int t=pt.func();//疑问:虚函数此时还能正常调用吗?printf("size:%d,t=%d",sizeof(point),t);//程序输出"size:16,t=0"今天在看别人的源码时发现类似这样的代码,以前好像在哪本书上看到过,说类实例中除了有成员变量之外还有编译器添加的虚函数表的指针.那么以上代码中memset不是会把pt中的"虚函数表指针"清除吗?如果会,pt.func();还能正常调用吗?
从输出结果和跟踪调试,发现程序一切正常.今天就是想求证一下,上面这样的代码到底有没有问题?是不是与特定的编译器有关?
解决方案 »
- 图像识别的问题
- 怎么让父窗口不透明,子窗口半透明?
- 如何在SYSTEM进程中访问注册表下HKEY_CURRENT_USER
- 串口传输位图
- 请教一个很弱智的问题,怎样用CFile类来创建一个文件,然后向其读写数据
- MDI的程序AfxOleInit是在InitInstance()中设置的,请问大家.....
- VC中怎么永久的增加对象库?
- <求助>我想用ATL做一个能画线的组件,第一次做这方面的东西,请过来人帮忙,分不够在给!!!
- 大家有看过the c++ programming language (special edition)英文版的吗?我觉得这本书巨烂!大家进来讨论讨论!
- 有谁知道小手形状的鼠标的IDC _?
- 看com本质论的套件有点糊涂
- vs2005及以上的版本用多了,今天发现居然忘了vc6.0怎么添加头文件和源文件
如果对象没有用到虚技术, 那么就可以使用memset,因为这时该模型呈现出bitwize语意, 也就是说对应对象的这块内存就想看上去一样,背后没什么隐藏的东西, 可以逐位拷贝.
pt.func地址写好了。
直接call。
这样出错了,会把vtbl指针失效
A是基类, B是派生类B(const B& obj):A(obj){........};
调用方式如下:B b1(xx);B b2=b1; b1 肯定有虚函数表的维护,b2 也有,, 你说b1的数据拷到b2的时候, b2的虚函数表有没有变动过????
楼主,及楼上各位大牛,能帮忙解答一下嘛 谢谢了啊
point *pt = new point(10,20,30);
memset(&pt,0,sizeof(point));
int t=pt->func();//疑问:虚函数此时还能正常调用吗?printf("size:%d,t=%d",sizeof(point),t);//程序输出"size:16,t=0"你分别看这两种写法的反汇编就知道原因了,具体原因是这样的:
首先,如果你用对象,因为你用对象,已经失去的多态的意义,也就是编译过后的程序中对于这样的代码:
pt.func()因为它的地址不会变所以就直接用func函数所在的地址替换掉,也就是所谓的你更改的virtal table point的指针也是正常运行的,因为这里并不依靠pvtr.也就是说没有用到多态的地方是不会影响你的程序执行的,但是如果你更改成我给出的Code的话,你运行肯定会当掉,因为这里要依靠pvtr指针,而这时的指针已经为空了,所以当然会当掉,说到这里估计你已经知道原因了.
尽管没有重新写但是更改还是很多,我们公司就修改了GCC, OPEN64等,所以重新写一个是没有意义的,更改才比较现实,毕竟这么优秀的工具不用自己要重新写当然就没有多大的意义了!