C++继承和强制转换调试结果不能理解。 ((FBase)child).Set();这行居然能通过编译,果然我的语言基础还是不行,求高人解答。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 派生类对象转基类对象貌似有临时变量产生。FBase* pBase = (FBase*)&child;FBase* pBase2 = &(FBase)child;FBase* pBase3 = &(FBase)child;你会发现这3个值都不相同。而且你也可以在set中把this的值打印出来,由于是单继承,基类对象会和派生类对象地址相同。 这正是虚函数的作用,你把virtual去掉就不一样了。 雖然可以強制轉換 ((FBase)child) 但是不代表轉換過後會更改child的任何信息吧,只是新產生了一個FBase的對象, 而這個對象你沒有定義,由程序自己建了一塊區域然後執行了Set 跟Child沒有什麼關係把 ? 我的理解是這樣 有問題請大神指點~~~ 开调试器看了一下: 此处仅仅是强制转换,(FBase) child , 而child这个实例无任何改变,,(FBase) child 用的是child的FBase部分。 上个图一目了然。 这是因为virtual的结果,当一个类的成员函数声明为virtual时,表示这是一个虚函数,其子类同样的名称函数也会继承这个性质当类进行强制转换的时候,意思就是把这个类当成另一个类,但调用虚函数时,却执行的是其创建时的类型函数,而不会执行转换后的,因为虚函数会在类中使用一个指针,这个指针指向虚函数表,通过间接来调用函数,这个指针值是在创建时赋予的,类的转换并不会自动改变类实例的值,也就是这个指针值不管你怎么转换,都是不会改变的,所以调用的时候,一定是它创建时的那个类型的函数。 // ss.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>using namespace std;class FBase{public: virtual void Set() { info = _T("FBase"); } void PrintInfo() { _tprintf(_T("%s\n"), info); }protected: TCHAR *info;};class FChild : public FBase{public: void Set() { info = _T("FChild"); }};int _tmain(int argc, _TCHAR* argv[]){ FChild child; child.Set(); child.PrintInfo(); ((FBase)child).Set(); child.PrintInfo(); FBase base; base.Set(); base.PrintInfo(); system("pause"); return 0;}从图中调试的情况来看,执行((FBase)child).Set(); 这一句时,调用的是 FChild::Set() ,因为 Set 函数是虚函数,子类可以改写父类的实现,你把 child 强制转换为 FBase 类型,生成了一个 FBase 类型的无名变量,但是这并不能改变什么,这个无名变量中的 Set 函数还是 FChild::Set() ,而不是 FBase::Set() ,所以最终还是调用了子类的 Set() 函数。 程序可以运行,但是总提醒no symbols loaded for user32.dll 关于网络编程? 现在的保安和保镖有嘛区别 ?? 晒一晒刚做好的界面 自己用SQL2000做了一个简单的客户数据 但不知道怎么与VC联系起来。。高人指教啊 本人菜鸟 如何解决重复性的问题. vc++ 多文档的问题 哪有硬盘读写的资料 请教有关Winsock编程的问题! WININET.DLL编程中的FTPOpenFile问题,用21端口可以,别的端口就打不开了 如获取系统已经安装的软件信息 VS2008 IDE代码编辑窗口TAB变成了小箭头空格变成了小点
FBase* pBase2 = &(FBase)child;
FBase* pBase3 = &(FBase)child;你会发现这3个值都不相同。而且你也可以在set中把this的值打印出来,由于是单继承,基类对象会和派生类对象地址相同。
开调试器看了一下: 此处仅仅是强制转换,(FBase) child , 而child这个实例无任何改变,,(FBase) child 用的是child的FBase部分。 上个图一目了然。
这是因为virtual的结果,当一个类的成员函数声明为virtual时,表示这是一个虚函数,其子类同样的名称函数也会继承这个性质当类进行强制转换的时候,意思就是把这个类当成另一个类,但调用虚函数时,却执行的是其创建时的类型函数,而不会执行转换后的,因为虚函数会在类中使用一个指针,这个指针指向虚函数表,通过间接来调用函数,这个指针值是在创建时赋予的,类的转换并不会自动改变类实例的值,也就是这个指针值不管你怎么转换,都是不会改变的,所以调用的时候,一定是它创建时的那个类型的函数。
//#include "stdafx.h"
#include <iostream>
using namespace std;class FBase
{
public:
virtual void Set()
{
info = _T("FBase");
}
void PrintInfo()
{
_tprintf(_T("%s\n"), info);
}
protected:
TCHAR *info;
};class FChild : public FBase
{
public:
void Set()
{
info = _T("FChild");
}
};int _tmain(int argc, _TCHAR* argv[])
{
FChild child;
child.Set();
child.PrintInfo();
((FBase)child).Set();
child.PrintInfo();
FBase base;
base.Set();
base.PrintInfo();
system("pause");
return 0;
}从图中调试的情况来看,执行((FBase)child).Set(); 这一句时,调用的是 FChild::Set() ,因为 Set 函数是虚函数,子类可以改写父类的实现,你把 child 强制转换为 FBase 类型,生成了一个 FBase 类型的无名变量,但是这并不能改变什么,这个无名变量中的 Set 函数还是 FChild::Set() ,而不是 FBase::Set() ,所以最终还是调用了子类的 Set() 函数。