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++@子类类型转换为父类类型的更多相关文章

  1. cocos2d-x getParent() 获得一个父类的一个node型指针,转换为父类类型

    void CenterLayer::zhanzheng(CCObject* pSender){ ((GameScene*)this->getParent())->showLayer(Gam ...

  2. 小问题,小细节要注意(string类型转换为bool类型)

    一个表中的推荐字段是bit类型的,添加的时候推荐有两个值,如<asp:RadioButtonList ID="RadioButtonList1" runat="se ...

  3. c++ string类型转换为char *类型

    string 是c++标准库里面其中一个,封装了对字符串的操作 把string转换为char* 有3中方法: 1.data 如: string str="abc"; char *p ...

  4. 注意SSIS中的DT_NUMERIC类型转换为字符类型(比如DT_WSTR)时,会截断小数点前的0

    我们知道SSIS中有许多数据类型,如下图所示: 但是DT_NUMERIC这个类型有个陷进要注意,我们来做个实验,随便定义一个String类型的SSIS包变量,然后打开该变量表达式窗口: 在变量表达式窗 ...

  5. Java进阶(二十三)java中long类型转换为int类型

    java中long类型转换为int类型 由int类型转换为long类型是向上转换,可以直接进行隐式转换,但由long类型转换为int类型是向下转换,可能会出现数据溢出情况: 主要以下几种转换方法,供参 ...

  6. Qt中实现将float类型转换为QString类型

    在使用Qt Creator编程时,难免会用到将float类型转换为QString类型的时候下面是我所有的方法: 1. 将QString类型转化为float类型,很简单 QString data; fl ...

  7. 深度学习原理与框架-Tensorflow基本操作-mnist数据集的逻辑回归 1.tf.matmul(点乘操作) 2.tf.equal(对应位置是否相等) 3.tf.cast(将布尔类型转换为数值类型) 4.tf.argmax(返回最大值的索引) 5.tf.nn.softmax(计算softmax概率值) 6.tf.train.GradientDescentOptimizer(损失值梯度下降器)

    1. tf.matmul(X, w) # 进行点乘操作 参数说明:X,w都表示输入的数据, 2.tf.equal(x, y) # 比较两个数据对应位置的数是否相等,返回值为True,或者False 参 ...

  8. python中bytes类型转换为str类型

    使用的原因:基于URL解析报文的时候,要使用str类型,但是提供的确实bytes类型,报错: TypeError: must be str, not bytes 所以就把bytes类型转换为str类型 ...

  9. Date类型转换为Integer类型

    Date类型转换为Integer类型: Integer date = Integer.valueOf(String.valueOf(new SimpleDateFormat("yyyyMMd ...

随机推荐

  1. 教学目标的表述方式──行为目标的ABCD表述法

    教学目标应规定学生在教学活动结束后能表现出什么样的学业行为,并限定学生学习过程中知识.技能的获得和情感态度发展的层次.范围.方式及变化效果的量度.对每节课教学目标的准确表述,可以充分发挥教学目标在教学 ...

  2. julia下载QQ.jl

    julia下载QQ.jl #=""" julia下载QQ.jl 从http://im.qq.com/pcqq/页面中提取出QQ的下载地址,并下载. 2016年4月1日 1 ...

  3. 实现viewpager下的圆点滑动

    在Drawable目录下创建资源文件 使用shape标签画出背景圆点与当前圆点 背景圆点: <?xml version="1.0" encoding="utf-8& ...

  4. paramiko堡垒机、线程及锁

    1.使用paramiko实现ssh连接和scp拷贝 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 1.1 SSHClient 用于连接远 ...

  5. BZOJ 1045 糖果传递

    奇怪的式子.最后发现取中位数. #include<iostream> #include<cstdio> #include<cstring> #include< ...

  6. "无意义"的div和span标签

    HTML <div> 元素是块级元素,它是可用于组合其他 HTML 元素的容器.<div>元素没有特定的含义.除此之外,由于它属于块级元素,浏览器会在其前后显示折行.如果与 C ...

  7. 【LEETCODE OJ】Binary Tree Postorder Traversal

    Problem Link: http://oj.leetcode.com/problems/binary-tree-postorder-traversal/ The post-order-traver ...

  8. Thread和Service应用场合的区别

    Thread和Service的区别: 1) Thread 是程序执行的最小单元,它是分配CPU的基本单位,可以用 Thread 来执行一些异步的操作. 如果是Local Service,那么对应的 S ...

  9. 使用RBL拦截垃圾邮件

    1.   sbl-xbl.spamhaus.org  2    bl.spamcop.net  3    zen.spamhaus.org

  10. WP8.1 实现Continuation程序(打开文件,保存文件等)

    以保存文件为例 首先,在项目中加入ContinuationManager.cs类,以及SuspensionManager.cs类. 其次,在App.xaml.cs中,完成如下步骤: 1. 添加Cont ...