((FBase)child).Set();
这行居然能通过编译,果然我的语言基础还是不行,求高人解答。

解决方案 »

  1.   

    派生类对象转基类对象貌似有临时变量产生。FBase* pBase = (FBase*)&child;
    FBase* pBase2 = &(FBase)child;
    FBase* pBase3 = &(FBase)child;你会发现这3个值都不相同。而且你也可以在set中把this的值打印出来,由于是单继承,基类对象会和派生类对象地址相同。
      

  2.   

    这正是虚函数的作用,你把virtual去掉就不一样了。
      

  3.   

    雖然可以強制轉換 ((FBase)child)   但是不代表轉換過後會更改child的任何信息吧,只是新產生了一個FBase的對象, 而這個對象你沒有定義,由程序自己建了一塊區域然後執行了Set 跟Child沒有什麼關係把 ? 我的理解是這樣  有問題請大神指點~~~
      

  4.   


    开调试器看了一下: 此处仅仅是强制转换,(FBase) child , 而child这个实例无任何改变,,(FBase) child 用的是child的FBase部分。 上个图一目了然。
      

  5.   


    这是因为virtual的结果,当一个类的成员函数声明为virtual时,表示这是一个虚函数,其子类同样的名称函数也会继承这个性质当类进行强制转换的时候,意思就是把这个类当成另一个类,但调用虚函数时,却执行的是其创建时的类型函数,而不会执行转换后的,因为虚函数会在类中使用一个指针,这个指针指向虚函数表,通过间接来调用函数,这个指针值是在创建时赋予的,类的转换并不会自动改变类实例的值,也就是这个指针值不管你怎么转换,都是不会改变的,所以调用的时候,一定是它创建时的那个类型的函数。
      

  6.   

    // 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() 函数。