posts - 1,  comments - 2,  trackbacks - 0

C++ Blog,这名太专业了,让人有点害怕,特别是向我这种C++的半瓶醋,真害怕玷污了C++这个词啊!
我从没写过Blog,向这种专业方面的就更没写过了,主要目的还是来看别人的Blog,并学习的!呵呵
今天第一次写,实在不知道写点什么,就还是提个问题吧。前几天讨论过一个指针强制转换的问题。测试代码如下:

#include <iostream>
using namespace std;

class Base1
{
public:
    virtual void foo(){cout
<<"Base1    foo"<<endl;};
    virtual void foo1(){cout
<<"Base1   foo1"<<endl;};
};

class Base2
{
public:
    virtual void foo2(){cout
<<"Base2    foo2"<<endl;};
    virtual void foo3(){cout
<<"Base2    foo3"<<endl;};
};

class Derived : 
public Base1, public Base2
{

};
int main()
{
 Derived a;
  (static_cast
<Base1*>((LPVOID)&a))->foo1();//调用Base1.foo1
 (static_cast
<Base1*>(&a))->foo1(); //调用Base1.foo1

 (static_cast
<Base2*>((LPVOID)&a))->foo2();//调用Base1.foo
 (static_cast
<Base2*>(&a))->foo2();//调用Base2.foo2

return 
0;
}


前两个结果都很正确,将a强制转换为其基类的指针,调用基类的函数。
而对于第三个第四个,它们得到的结果却不一样。
第三个我是这样理解的:由于强制转换之后,转换之后的指针根据虚函数表去调用函数,而由于LPVOID的存在,(static_cast<Base2*>((LPVOID)&a))->foo2();调用的是 Derived虚函数表中第一个函数指针所指向的函数,也就是Base1的foo。
因此,对于,(static_cast<Base1*>((LPVOID)&a))->foo1();其调用的也是 Derived中虚函数表中的第二个函数。
第四个的调用是正确的。
因此,如果在申明 Derived的时候,改变一下继承的顺序,class Derived : public Base2, public Base1
那么得到的结果将是(static_cast<Base1*>((LPVOID)&a))->foo1();将会调用虚函数表中的第二个函数,为Base2.foo3。
如果得到的类型是LPVOID类型的,直接使用static_cast转换就会出错,这是我前几天碰到的一个问题,可能是我的设计有问题,不过应该也有解决的方案,我的思路是先计算Derived中基类的偏移,然后再进行转换,不过我还不知道怎么实现,不知道谁能帮我解决或者有更好的解决方案!
第一次写Blog,欢迎大家光临和教导!谢谢^_^

posted on 2008-05-12 13:17 Guanghong(随意飘荡) 阅读(1231) 评论(2)  编辑 收藏 引用

FeedBack:
# re: LPVOID,static_cast 的问题
2008-05-12 17:16 | 啸天猪
使用强制转换尤其是void * 就意味着你在C++的类型检查系统上开了一个缺口,所以你得自己负责所有的后果。

Derived有两个基类,所以它的对象中会包含2个Vptr,而你使用的编译器在实现中应该是将第一个基类的Vptr放在对象的起始处,这样(void *) &a 与statci_cast<Base1 *>(&a) 在数值上相同的;另一方面,(void *) &a 与static_cast<Base2 *>(&a)在数值上是不同的,后者会根据Derived和Base2之间的关系对指针值进行调整,以保证它指向正确的Vptr,即基类Base2对应的Vptr。

程序中的3处在使用static_cast之前先执行了void *强制转换,这样类型信息就丢失了,因而static_cast<Base2 *> ( (void *) &a)得到的结果指向基类Base1对应的vptr,而不是基类Base2对应的vptr

“计算Derived中基类的偏移”这样的事情是和编译器实现紧密相关的,不具备可移植性,我觉得你不该采用这样的解决思路。  回复  更多评论
  
# re: LPVOID,static_cast 的问题
2008-05-13 09:25 | Guanghong(随意飘荡)
嗯,谢谢“啸天猪”^_^
是我的思路有问题!转换成void*之后,多态的信息就丢失了  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航:   博客园   博客园最新博文   博问   管理


<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用链接

留言簿(1)

随笔档案

搜索

  •  

最新评论