码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-06-07 23:25:26      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

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;
    }

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

标签:

原文地址:http://www.cnblogs.com/kwseeker-bolgs/p/4559624.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!