C++继承和强制转换调试结果不能理解。

xfan1024 2014-05-22 02:16:17
类:
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");
}

};


执行如下代码:
	FChild	child;
child.Set();
child.PrintInfo();
((FBase)child).Set();
child.PrintInfo();


child.Set() 把info设置成了"FChild"

((FBase)child).Set() 把info设置成了“FBase”

但为什么两次打印出来的都是“FChild”呢?
...全文
201 12 打赏 收藏 举报
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
xfan1024 2014-05-26
观察了下内存,发现强制转换其实是复制构造,也就是说我强制转换后已经不是我原来的东西了。谢谢大家。
  • 打赏
  • 举报
回复
caewow 2014-05-24
// 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() 函数。
  • 打赏
  • 举报
回复
unituniverse2 2014-05-24
虚函数的目的就是可以通过基类指针或引用调用实际的派生类成员函数
  • 打赏
  • 举报
回复
Starmean 2014-05-23
这是因为virtual的结果,当一个类的成员函数声明为virtual时,表示这是一个虚函数,其子类同样的名称函数也会继承这个性质 当类进行强制转换的时候,意思就是把这个类当成另一个类,但调用虚函数时,却执行的是其创建时的类型函数,而不会执行转换后的,因为虚函数会在类中使用一个指针,这个指针指向虚函数表,通过间接来调用函数,这个指针值是在创建时赋予的,类的转换并不会自动改变类实例的值,也就是这个指针值不管你怎么转换,都是不会改变的,所以调用的时候,一定是它创建时的那个类型的函数。
  • 打赏
  • 举报
回复
刹那神伤 2014-05-23
雖然可以強制轉換 ((FBase)child) 但是不代表轉換過後會更改child的任何信息吧,只是新產生了一個FBase的對象, 而這個對象你沒有定義,由程序自己建了一塊區域然後執行了Set 跟Child沒有什麼關係把 ? 我的理解是這樣 有問題請大神指點~~~
  • 打赏
  • 举报
回复
Jarrylogin 2014-05-23
引用 7 楼 sir870405 的回复:
雖然可以強制轉換 ((FBase)child) 但是不代表轉換過後會更改child的任何信息吧,只是新產生了一個FBase的對象, 而這個對象你沒有定義,由程序自己建了一塊區域然後執行了Set 跟Child沒有什麼關係把 ?

我的理解是這樣 有問題請大神指點~~~


开调试器看了一下: 此处仅仅是强制转换,(FBase) child , 而child这个实例无任何改变,,(FBase) child 用的是child的FBase部分。 上个图一目了然。
  • 打赏
  • 举报
回复
信阳毛尖 2014-05-22
virtual 重写/覆盖
  • 打赏
  • 举报
回复
zhousitiaoda 2014-05-22
派生类对象转基类对象貌似有临时变量产生。

FBase* pBase = (FBase*)&child;
FBase* pBase2 = &(FBase)child;
FBase* pBase3 = &(FBase)child;
你会发现这3个值都不相同。而且你也可以在set中把this的值打印出来,由于是单继承,基类对象会和派生类对象地址相同。
  • 打赏
  • 举报
回复
大_猫 2014-05-22
你C++书看少了。这是函数覆盖问题。 C++有函数重载、覆盖、隐藏。你自己好好看看就知道了。
  • 打赏
  • 举报
回复
zmyouren1983 2014-05-22
child.FBase::Set();
  • 打赏
  • 举报
回复
baichi4141 2014-05-22
((FBase)child).Set();
这行居然能通过编译,果然我的语言基础还是不行,求高人解答。
  • 打赏
  • 举报
回复
encoderlee 版主 2014-05-22
这正是虚函数的作用,你把virtual去掉就不一样了。
  • 打赏
  • 举报
回复
相关推荐
发帖
VC/MFC

1.6w+

社区成员

VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
帖子事件
创建了帖子
2014-05-22 02:16
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……