论坛: 编程破解 标题: 关于类强制转换的一点疑问 复制本贴地址    
作者: Garu [syshunter]    版主   登录
VC下对静态EDIT的操作,如下代码:
((CEdit *)GetDlgItem(IDC_EDIT1))->SetLimitText(20);
突然产生一点疑问,就是类的强制转换的问题,写了如下测试代码:
代码:
#include <iostream>
using namespace std;

class Base
{
public:
Base(int d=0) { data=d; }
virtual void SetData(int);
virtual void Display(void);
protected:
int data;
};
void Base::SetData(int d)
{
data=d;
}
void Base::Display(void)
{
cout<<"In Base :"<<data<<endl;
}

class Sub:public Base
{
public:
int GetData(void);
void Display(void);
};
int Sub::GetData(void)
{
return data;
}
void Sub::Display(void)
{
cout<<"In Sub: "<<data<<endl;
}

void main(void)
{
Base *pbase=new Base();
Sub *psub=(Sub *)pbase;
cout<<psub->GetData()<<endl; //调用的是Sub::GetData()
psub->Display(); //为什么是Base::Display()?
delete pbase;
}


类型强制转换不能够实现多态?

在网吧上网,没条件编译,有什么错大家指正

[此贴被 Garu(syshunter) 在 08月18日13时36分 编辑过]

地主 发表时间: 04-08-18 12:56

回复: Garu [syshunter]   版主   登录
Base *pbase=new Base();
Sub *psub=(Sub *)pbase;
psub所指的堆是Base,还是Sub?
是Base的话怎么能访问到GetData?
是Sub的话虚函数调用的怎么是Base的?

如果是属于强制类型转换的话。假设有下面这个函数:
fun(Base *pb)
{
    pb->Display();
}
很显然可以是多态,我们定义Sub *abc=new Sub,调用fun(abc)运行的是Sub::Display()。那么从实参Sub类到形参Base类进行了怎样的变化?是强制类型转换还是什么别的?


[此贴被 Garu(syshunter) 在 08月18日15时00分 编辑过]

B1层 发表时间: 04-08-18 14:52

回复: Garu [syshunter]   版主   登录
找到答案,原因:对虚函数运行机制理解不够透彻。

FAQ文献: http://www.sunistudio.com/cppfaq/virtual-functions.html


摘要:

虚函数允许派生类取代基类所提供的实现。编译器确保当对象为派生类时,取代者(译注:即派生类的实现)总是被调用,即使对象是使用基类指针访问而不是派生类的指针。这样就允许基类的算法被派生类取代,即使用户不知道派生类的细节。

虚成员函数是动态确定的(在运行时)。也就是说,成员函数(在运行时)被动态地选择,该选择基于对象的类型,而不是指向该对象的指针/引用的类型。这被称作“动态绑定”。


当你有一个对象的指针,而对象实际是该指针类型的派生类(例如:一个 Vehicle*指针实际指向一个Car 对象)。由此有两种类型:指针的(静态)类型(在此是Verhicle),和指向的对象的(动态)类型(在此是Car)。

静态类型意味着成员函数调用的合法性被尽可能早地检查:编译器在编译时。编译器用指针的静态类型决定成员函数调用是否合法。如果指针类型能够处理成员函数,那么指针所指对象当然能很好的处理它。例如,如果 Vehicle 有某个成员函数,则由于Car是一种Vehicle,那么Car 当然也有该成员函数。

动态绑定意味着成员函数调用的代码地址在最终时刻才被决定:基于运行时的对象动态类型。因为绑定到实际被调用的代码这个过程是动态完成的(在运行时),所以被称为“动态绑定”。动态绑定是虚函数导致的结果之一。


非虚成员函数是静态确定的。也就是说,该成员函数(在编译时)被静态地选择,该选择基于指象对象的指针(或引用)的类型。



B2层 发表时间: 04-08-18 20:01

回复: Garu [syshunter]   版主   登录
由以上得出结论:

GetDlgItem(ID)返回的是CWnd指针,但该指针所指向的却是对应控件类的堆空间。

不知道理解是否有错,希望大家踊跃指正。

B3层 发表时间: 04-08-18 20:06

回复: TecZm [teczm]   版主   登录
强啊!

B4层 发表时间: 04-08-19 09:50

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号