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;
}
C++@子类类型转换为父类类型的更多相关文章
- cocos2d-x getParent() 获得一个父类的一个node型指针,转换为父类类型
void CenterLayer::zhanzheng(CCObject* pSender){ ((GameScene*)this->getParent())->showLayer(Gam ...
- 小问题,小细节要注意(string类型转换为bool类型)
一个表中的推荐字段是bit类型的,添加的时候推荐有两个值,如<asp:RadioButtonList ID="RadioButtonList1" runat="se ...
- c++ string类型转换为char *类型
string 是c++标准库里面其中一个,封装了对字符串的操作 把string转换为char* 有3中方法: 1.data 如: string str="abc"; char *p ...
- 注意SSIS中的DT_NUMERIC类型转换为字符类型(比如DT_WSTR)时,会截断小数点前的0
我们知道SSIS中有许多数据类型,如下图所示: 但是DT_NUMERIC这个类型有个陷进要注意,我们来做个实验,随便定义一个String类型的SSIS包变量,然后打开该变量表达式窗口: 在变量表达式窗 ...
- Java进阶(二十三)java中long类型转换为int类型
java中long类型转换为int类型 由int类型转换为long类型是向上转换,可以直接进行隐式转换,但由long类型转换为int类型是向下转换,可能会出现数据溢出情况: 主要以下几种转换方法,供参 ...
- Qt中实现将float类型转换为QString类型
在使用Qt Creator编程时,难免会用到将float类型转换为QString类型的时候下面是我所有的方法: 1. 将QString类型转化为float类型,很简单 QString data; fl ...
- 深度学习原理与框架-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 参 ...
- python中bytes类型转换为str类型
使用的原因:基于URL解析报文的时候,要使用str类型,但是提供的确实bytes类型,报错: TypeError: must be str, not bytes 所以就把bytes类型转换为str类型 ...
- Date类型转换为Integer类型
Date类型转换为Integer类型: Integer date = Integer.valueOf(String.valueOf(new SimpleDateFormat("yyyyMMd ...
随机推荐
- 虚拟机安装Centos版本的linux
选择自定义安装,然后一路确定下去,对了,Centos的版本一定要高,比如centos 6,太低安装会出问题
- android:强制关闭其他应用
强制关闭其他应用,可以使用ActivityManager,首先需要获取(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 然后可以 ...
- poj2184 背包
//Accepted 1492 KB 110 ms //背包 //把si看成weight,Fi看成value,这可以表示成当dp[j]=max(dp[j-weight[i]]+value[i]) // ...
- poj1458
//Accepted 4112 KB 16 ms //最长公共子串 #include <cstdio> #include <cstring> #include <iost ...
- mysql批量写入
MySQL批量写入语法是: INSERT INTO table (field1,field2,field3) VALUES (“a”,”b”,”c”), (“a1”,”b1”,”c1”),(“a2”, ...
- SAP 中如何寻找增强
http://blog.csdn.net/edifierliu/article/details/5978824 查找SAP标准事务代码中使用的BADI: 在SE24中,查看类对象CL_EXITHAND ...
- postgreSQL9.1忘记postgres用户密码怎么办
在网络上找了一篇文章http://www.linuxidc.com/Linux/2010-04/25232.htm,如下: Ubuntu 9.10下PostgreSQL 8.4忘记密码的解决方法 Ub ...
- HDU 4576
http://acm.hdu.edu.cn/showproblem.php?pid=4576 题意:给一个1-n的环,m次操作,每次操作顺时针或逆时针走w步,求最后落在[l,r]区间的概率 dp[i] ...
- Why does my ListView scroll to the top when navigating backwards?
I’ve seen a few people asking this question. They have a page which contains a ListView and when an ...
- NSFileHandle 、 沙箱机制 、 属性列表
1 使用NSFilehandle进行数据读写 1.1 问题 NSFileManager用于实现对文件的操作,而NSFileHandle是IOS提供的对文件内容(二进制数据)进行操作的类,例如数据的读写 ...