常量替换帖 http://topic.csdn.net/u/20081213/17/8f4b5a1d-e6bf-43fc-98d9-ccd25777f4a9.html
#include <iostream>
#include <string.h>
using namespace std;
class aa
{
public:
virtual void ff1()
{
cout<<"111111111111"<<endl;
}
};
class bb
{
public:
virtual void ff2()
{
cout<<"22222222222"<<endl;
}
};
void main()
{
aa a;
bb b;
aa* l=&a;
a.ff1(); //换之前, 输出了“111111111111111”
l->ff1(); //换之前, 输出了“111111111111111”
cout<<*((int*)&a)<<endl; //a中vtbl表的地址
cout<<*((int*)&b)<<endl; //b中vtbl表的地址
memcpy(&a,&b,4); //vtbl表的地址交换
cout<<*((int*)&a)<<endl; //a和b的vtbl表一样了
cout<<*((int*)&b)<<endl;
l->ff1(); //因为换了,所以输出了“22222222222222”
a.ff1(); //为什么输出了“111111111111111”
system("pause");
}
16 个解决方案
#1
#2
虚函数,多态,只对指针和引用有效
#3
up
不过还是得学习楼主的钻研精神 呵呵
#4
哦 引用的我试过了,果然也是输出“22222222222”,我就想不通了,编译器怎么这么牛B,我把对象里的内容改了,他还能找到原来的函数,想不通想不通
#5
不明白,期待高手解决 !!!
#6
哎 可惜汇编学的很垃圾,不然可以到汇编码里去看看,后来的朋友把这个代码的汇编码解释一下好么,谢谢!!
#7
up
#8
aa a;
a.ff1();
当你这样去调用的函数的时候,编译器是在编译的时候就根据a的类型aa,确定了它要调用的函数ff1的地址
但如果是指针或许引用,则编译器编译的时候不绑定调用的函数,而是在运行的时候才通过虚表去查,在去调用具体的函数
a.ff1();
当你这样去调用的函数的时候,编译器是在编译的时候就根据a的类型aa,确定了它要调用的函数ff1的地址
但如果是指针或许引用,则编译器编译的时候不绑定调用的函数,而是在运行的时候才通过虚表去查,在去调用具体的函数
#9
哦 原来是这样,也就是说编译器看到a.ff1()首先想到的是去aa类里面去找ff(),怪不的改了vtbl也没用,原来根本就没访问这里啊
还想问问星羽,这些是哪方面的知识啊,我看的书里面都不讲这些
#10
跟汇编没有关系的
你的虚表确实一个更换了
但是调用虚表就必须用引用或者指针
对象是不会用到虚表的
会直接用一个在全局空间的函数的地址指针
理解?
#11
恩 了解了,谢谢
#12
学习
#13
具体调用那个函数和如何调用关系很大。 一种是动态确定(RTTI),一种静态绑定。
如果直接使用实例,那么编译器自然就可以认为你使用的就是确定的类型,(因为它不nb,不知道你会改变他的vptr),静态绑定。
如果使用的指针 or 引用,编译器就好衡量,这个确定的类型到底是什么,于是,对于所有的virturl使用vtbl里面的数值。
不过楼主那种转法没有可移植性的,作为学习完全支持,不建议实际使用。就是可以移植,也会让其他人很郁闷的。
#14
用一句耳熟能详的话:没有后绑定,就没有多态。
#15
顶这个,也想学习学习!
#16
不错的尝试方法,可以增长些见识,学习了
#1
看雪有几篇帖子或许可以看看
http://bbs.pediy.com/showthread.php?t=60538
http://bbs.pediy.com/showthread.php?t=78341
http://bbs.pediy.com/showthread.php?t=71775
http://bbs.pediy.com/showthread.php?t=60538
http://bbs.pediy.com/showthread.php?t=78341
http://bbs.pediy.com/showthread.php?t=71775
#2
虚函数,多态,只对指针和引用有效
#3
up
不过还是得学习楼主的钻研精神 呵呵
#4
哦 引用的我试过了,果然也是输出“22222222222”,我就想不通了,编译器怎么这么牛B,我把对象里的内容改了,他还能找到原来的函数,想不通想不通
#5
不明白,期待高手解决 !!!
#6
哎 可惜汇编学的很垃圾,不然可以到汇编码里去看看,后来的朋友把这个代码的汇编码解释一下好么,谢谢!!
#7
up
#8
aa a;
a.ff1();
当你这样去调用的函数的时候,编译器是在编译的时候就根据a的类型aa,确定了它要调用的函数ff1的地址
但如果是指针或许引用,则编译器编译的时候不绑定调用的函数,而是在运行的时候才通过虚表去查,在去调用具体的函数
a.ff1();
当你这样去调用的函数的时候,编译器是在编译的时候就根据a的类型aa,确定了它要调用的函数ff1的地址
但如果是指针或许引用,则编译器编译的时候不绑定调用的函数,而是在运行的时候才通过虚表去查,在去调用具体的函数
#9
哦 原来是这样,也就是说编译器看到a.ff1()首先想到的是去aa类里面去找ff(),怪不的改了vtbl也没用,原来根本就没访问这里啊
还想问问星羽,这些是哪方面的知识啊,我看的书里面都不讲这些
#10
跟汇编没有关系的
你的虚表确实一个更换了
但是调用虚表就必须用引用或者指针
对象是不会用到虚表的
会直接用一个在全局空间的函数的地址指针
理解?
#11
恩 了解了,谢谢
#12
学习
#13
具体调用那个函数和如何调用关系很大。 一种是动态确定(RTTI),一种静态绑定。
如果直接使用实例,那么编译器自然就可以认为你使用的就是确定的类型,(因为它不nb,不知道你会改变他的vptr),静态绑定。
如果使用的指针 or 引用,编译器就好衡量,这个确定的类型到底是什么,于是,对于所有的virturl使用vtbl里面的数值。
不过楼主那种转法没有可移植性的,作为学习完全支持,不建议实际使用。就是可以移植,也会让其他人很郁闷的。
#14
用一句耳熟能详的话:没有后绑定,就没有多态。
#15
顶这个,也想学习学习!
#16
不错的尝试方法,可以增长些见识,学习了