• C++@子类类型转换为父类类型


    static_cast(*this) to a base class create a temporary copy.

    class Window {                                 // base class
    public:
      virtual void onResize() { ... }              // base onResize impl
      ...
    };
    
    class SpecialWindow: public Window {          // derived class
    public:
      virtual void onResize() {                   // derived onResize impl;
      static_cast<Window>(*this).onResize();      // cast *this to Window,
                                                  // then call its onResize;
                                                  // this doesn't work!
        ...                                       // do SpecialWindow-
      }                                           // specific stuff
    
      ...
    
    };        
    

    Effective C++: What you might not expect is that it does not invoke that function on the current object! Instead, the cast creates a new, temporary copy of the base class part of *this, then invokes onResize on the copy! 

    *******************************************************************************************

    Contrast:

    static_cast<Window>(*this)

    with:

    static_cast<Window&>(*this)

    One calls the copy constructor, the other does not. 

    *******************************************************************************************

    Because you are casting actual object not a pointer or reference. It's just the same with casting double to int creates new int - not reusing the part of double.

    double类型转换为int型会创建一个新的int型变量?

    *******************************************************************************************

    上面的句子static_cast<Window>(*this).onResize();千万别改成下面这样,那样会更悲惨!

      virtual void onResize()
        {
            static_cast<Window*>(this)->onResize(); //调用基类的onResize()
            derived_ = 2;
            std::cout <<"S" << " base_=" << base_ << ",derived=" << derived_ << std::endl;
        }

    实际上,可能只有C的高手初转C++,对C++对象的内存模型还不很清楚的情况下才会写成这样的代码。

    对一个指针,不论我们怎样强制转换,它指向的那段内存的内容并没有改变。
    函数把本类对象的指针强制转换为基类对象的指针,只意味着“通过这个指针只能访问基类的成员”了,而对象的内容并没有改变。onResize是虚函数,调用它是先通过对象中指向虚表的指针找到虚表,然后在虚表中找到onResize函数的指针,最后通过函数指针调用函数。  this指针强制转换后,内存没有改变,所以指向虚表的指针没有改变,所以它找到的虚表仍是派生类的虚表,自然找到的函数指针仍是派生类的onResize函数的指针,所以这里就成了一个无穷递归调用,结果就是消耗完栈空间。

    将函数修改为这样:你就会看到不断的输出ReCall.
        virtual void onResize()
        {
            std::cout<<"ReCall"<<endl;
            static_cast<Window*>(this)->onResize(); //调用基类的onResize()
            derived_ = 2;
            std::cout <<"S" << " base_=" << base_ << ",derived=" << derived_ << std::endl;
        }

  • 相关阅读:
    shell 调试
    shell中的函数参数
    shell脚本执行的区别
    《C# 语言学习笔记》——C# 简介
    【SVN】SVN使用教程总结
    SVN Unable to connect to a repository at URL问题解决
    前后端分离(三)
    前后端分离(二)
    前后端分离(一)
    【git】Git的使用
  • 原文地址:https://www.cnblogs.com/kwseeker-bolgs/p/4559624.html
Copyright © 2020-2023  润新知