派生的关系
CWnd
  |--CFrameWnd
         |---CMainFrame
===========================
问题
    指向CMainFrame的this指针,却用在了一处需要CWnd*参数类型的地方。(这是一个教程例子中出现的)
    我不明白指向派生类的指针放在了指向基类指针参数类型的地方?Why?备注:CButton::Create 
BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );中第四个参数出用的指向CMainFrame的this指针。希望大家帮我分析下,谢谢!

解决方案 »

  1.   

    你应该看看《Effictive c++》了,呵呵。
    举个例子吧
    class Person
    {
      ...
    };
    class Student:public Person
    {
      ...
    };
    void Dance(Person& p);  //人会跳舞,这个就相当于Create,用基类的指针(或引用),Create在CWnd中也有定义,这样就可以保证CButton CFrameWnd都可以用
    void Study(Student& S); //学生会学习...
    Person p;
    Student S;Dance(p);  //肯定正确
    Dance(s);   //也正确,学生也是人,也可以跳舞,相当于CMainFrame里面调用Study(p); //错误,人不都是学生
      

  2.   

    谢谢2楼,我就是想知道Dance(s)为什么正确,那一部分知识点会阐释这个过程?
      

  3.   

    呵呵,Create可以调用我没问题。
    我的疑问是:此例把指向派生类对象的this指针强制类型转换成了指向基类类型的指针,那么编译器限制指向派生类对象的指针去直接指向基类对象,只是为了提醒程序员犯(非本意的)低级错误?只要有把握就可以强类型转换?
      

  4.   

    这个Create()函数使用窗口类指针是因为要使用类里面的窗口句柄成员变量,改变是所有窗口类的特征。另外,将派生类对象转换为基类对象是合法的,反过来却不是合法的。因为前一种强制转换之后,无论如何用基类的函数操作都不会有用错类中的成员变量的问题,而后一种强制转换会导致派生类中有而基类中没有的函数对基类对象所没有的成员变量进行操作,这就导致用错数据或者内存访问越界(非法访问)。
      

  5.   

    你的疑问是:编译器限制指向派生类对象的指针去直接指向基类对象,这是对的;但是你的此例却是使用指向基类类型的指针的地方使用指向派生类对象的this指针,这不是强制类型转换,和你的疑问正好相反。
    对于你的疑问的例子是:比如一个函数需要CFrameWnd*指针,用CWnd*类型的指针去调用,就可能是错误的,编译器会警告,除非确定这个指针指向的就是CFrameWnd类型的对象才可以强制类型转换。
      

  6.   

    你可以参看一下<面向对象程序设计教程>,里面对类的派生与继承有比较清楚的阐述.其中尤其需要注意类型转换的方向性.
      

  7.   

    不好意思,我的表述实在是糟糕透了,感谢大家帮我分析。我看的书是比较入门级的,很多c++细节与用法都没有讲。比如,书上说构造函数不带返回值。但实际上构造函数带返回值,只不过不允许程序员自己定义返回值。
    我的意思是,书上说指向派生类对象的指针不能直接指向基类对象,
    但是我在例子中看到:指向CMainFrame的this指针,却用在了一处需要 CWnd* 参数类型的地方。运行也通过了。大家没有什么疑问吗?
    希望大家帮我分析下是怎么通过的,或者我应该用什么样的方法可以自己分析?谢谢!
      

  8.   

    我的意思是,书上说指向派生类对象的指针不能直接指向基类对象
    但是我在例子中看到:指向CMainFrame的this指针,却用在了一处需要 CWnd* 参数类型的地方。运行也通过了。
    -------------------------
    书上的意思和你看到的例子是正好相反的。
    书上是说:建立一个基类对象,你不能拿派生类对象的指针来指向他,把这个基类对象当成派生类对象来用。
    你看到的例子是:建立了一个派生类对象,用基类对象的指针来指向他,把这个派生类对象当基类对象来用,这是C++的多态,是完全合法而且是安全的。
      

  9.   


    this是指向派生类对象(CMainFrame)的指针,但是却用在了需要 CWnd* 参数类型的地方(CWnd是CMainFrame的间接基类)。Why?
    如果不是编译器帮助进行了常量地址的强制类型转换,那会是什么操作呢?
      

  10.   

    晕,函数的参数是在函数中定义的变量。你看到的是CMainFrame对象(内存区)的地址拷贝给了CWnd指针。