强制转换

结构体强制转换 结构体的强制类型转换 一.为什么写这篇文章 之前写代码的时候碰到了下面这种结构体的强制类型转换。当时就比较懵,因为刚开始学,很多东西可能不太了解。所以,现在写出来,分享一下,还希望能跟大家一起学习进步一下。 二.结构体的强制转换要注意的点 1.字节对齐 这一点是比较重要的,如果有不懂的同学,还得去看看一些大佬的解释。大家如果有看一些linux内核源码就会看到,原来的大神们对于字节对齐的把控。举个例子 通过下图两张图,大家可用看到在强制类型转换的时候,大神们已经在sk_buff中准备了一个缓冲区专门用来强制 阅读详情

 

class A{
public:
        void print1(){
                printf("1/n");
        }
        virtual void print2(){
                printf("2/n");
        }
};

class B : public A{
public:
        void print1(){
                printf("3/n", s);
        }
        virtual void print2(){
                printf("4/n", s);
        }
};

void print(){
    A* ap = new A();
    ap->print1();
    ap->print2();

    delete ap;
    ap = new B();
    ap->print1();
    ap->print2();

    delete ap;
    B* bp = (B*)new A();
    bp->print1();
    bp->print2();
}
以上程序的输出为:
1
2
1
4
3
2
这里面最后这个B* bp = (B*)new A();我是一点都不理解, 我原以为程序在这里报异常, 谁知却可以运行出让人目瞪口呆的结果出来.
我之所以有将报异常的印象, 是因为<<more effective c++>>上说专用于类类别转换的dynamic_cust会自动判断dynamic_cust是否成功, 对于指针来说如果结果是不能转换, 则指针变为NULL, 对于&引用则会抛异常出来.  而(B*)与dynamic<B*>() 的作用其实是相同的, 所以我以为二者会有相同的外在表现.

而实际上(B*)这种C语言的强制转换是缺乏这种是否可转的检查的, 因此程序能运行出结果出来, 但实际上这种结果只是全部可能的异常情况中看起来最正常的一种, 该段程序其它的可能包括导致程序崩溃等等.
后来我把那一段强制转换改成 :B* bp = dynamic_cast<B*>(new A());  之后, 发现程序运行时报野指针错误, "非法的对0x00000000的访问". 然后我在强制转换后加了一个判断
if(bp == NULL){
    printf("cust not allowed!/n" );
}
这才明显地看出来, dynamic_cast确实把该指针批向NULL了.   也就是说, 考试题中的代码实际上是不合法的.

另外我又更进一步做了如下的试验,
class C{
public:
        void print1(){
                printf("5/n");
        }
        virtual void print2(){
                printf("6/n");
        }
};

C* pc = (C*) new A();    //这种写法比考试题更无耻
pc->print1();
pc->print2();
程序居然还可以运行, 而且结果输出为:
5
2
唉, 看到这种结果我真是觉得有些无法解释. 应该是跟指向函数表的vptr虚函数指针有关系 <<inside C++ object model>>中对此有深入描述, 看来确实有必要读一下这本书了.......

20080707 注释:看过more effective c++ item24之后,对最后这个问题又有了新的理解。这种对指针的转型B* bp = (B*) new A(); 对于这当前的程序来说,完全是可以正常运行的,但也属于打擦边球,如果B对象中多一个 int i; 那么这个程序运行的结果就不可预测了。
       先说为什么现成这个程序可以正常运行。对于B来说print1非virtual函数,则编译器会直接根据指针bp的类型B*将其与B::print1() 连接起来。而对于print2, 则会根据vptr 虚函数指针去虚函数表去寻找准确的函数,然后动态绑定时发现bp所指的对象其实是A,因此就把bp->print2()指向对 A::print2()的调用。对于后台的与A完全无关的C类也可以强制转换并调用,其实道理也是完全一样的。
        再说为什么随遍添加几个类成员就可能让程序运行结果不可预测。A* ap = new A(), 导致在堆上分配了4个字节,这四个字节存储了vptr。而如果B中有一个int成员变量的话,则sizeof(B)=8, 而B* bp = (B*) ap导致进行了一个强制转换,指向堆上4个字节A对象的指针被强制标记为指向堆上8个字节B对象的指针。这样一来,程序就把4个字节上方4个节也也私自(相对于光明正大的new 或者malloc操作)据为已有,当程序试图操作这本不属于他的4个字节时,其结果是不可预料的。另外当前这个程序能否正常运行也依赖于编译器的实现,这个“非法的“程序由于不符合C++语法,因此无法保证它可以在全部依照C++标准而实现的编译器下编译并运行。从dynamic_cast操作的结果来看,C++对于此种强制转换也是拒绝的,因为cast的结果是一个NULL指针。

机器学习系列(1)_逻辑回归初步 1、总述 逻辑回归是应用非常广泛的一个分类机器学习算法,它将数据拟合到一个logit函数(或者叫做logistic函数)中,从而能够完成对事件发生的概率进行预测。 2、由来     要说逻辑回归,我们得追溯到线性回归,想必大家对线性回归都有一定的了解,即对于多维空间中存在的样本点,我们用特征的线性组合去拟合空间中点的分布和轨迹。如下图所示:     线性回归能对连续值结果进行预测, 阅读详情

相关推荐

告别手动转换!用腾讯云轻量服务器+QMT插件,5分钟搞定聚宽策略实盘(附完整源码)

本文详细介绍如何利用腾讯云轻量服务器和QMT插件快速实现聚宽策略的自动化实盘部署。通过云端信号中转站解决协议转换、信号缓存等核心问题,5分钟完成服务器配置,并附完整源码实现零改造实盘方案,显著提升量化交易效率。

weixin_28707739的博客 659

C语言 强制类型转换——《跟老吕学C》

强制类型转换是C语言中一个重要的特性,它允许我们显式地告诉编译器进行数据类型转换。然而,过度使用或错误使用强制类型转换可能会导致数据丢失、精度问题、程序崩溃等不可预测的结果。因此,在使用强制类型转换时,请务必谨慎并仔细考虑你的代码逻辑和数据类型。同时,也可以考虑使用函数封装、隐式转换、谨慎使用指针转换、使用联合体等替代方案来简化你的代码并提高代码的可读性和可维护性。

Python老吕的博客 1645

微信Dat文件转图片(文末含工具下载)

PC端微信dat图片转换为jpg格式

weixin_40704848的博客 8080

【C语言】强制转换

常规的数据类型强制转换,加入指针后,地址,函数等等的强制转换细节和示例程序

Goforyouqp的博客 2万+

ODrive0.5.5源码分析(1) ADC的处理

odrive 0.5.5 ADC

danger的博客 4307

浅谈“无人机通感一体化(ISAC)”

总的来说,通信和感知一体化是一个循序渐进的过程,是未来一个比较有潜力的发展场景,当然,需要研究的内容有很多,面临的挑战也有很多,但是它值得我们去探索和学习!

m0_69182322的博客 4200

深入理解C++强制类型转换

C++四种强制转换类型 static_cast reinterpret_cast const_cast dynamic_cast static_cast 静态转换,用于非多态类型,任何标准的转换都可以用它,不能用于两个互不相干的类型 可以理解为能进行隐式转换类型的使用它 代码示例: int i=1; double d=static_

double_happiness的博客 4176

深信服桌面云实战:从零部署到高效运维的配置全景指南

本文详细介绍了深信服桌面云从零部署到高效运维的全流程配置指南,涵盖硬件规划、平台部署、虚拟桌面发布、终端管理及性能优化等关键环节。特别强调了双万兆网络架构、分布式存储配置和智能调度功能的应用,帮助用户实现高性能、高可用的虚拟桌面环境。

weixin_28568819的博客 399

强制类型转换(int)、(int&)和(int*)的区别

我们先来看两行代码:float x=1.75,y=1.75; cout&lt;&lt;(int)x&lt;&lt;" "&lt;&lt;(int&amp;)y&lt;&lt;endl;输出为:1    1071644672首先呢,我们来看一下浮点数的格式:float是单精度32位,所以呢:符号位 (Sign):0代表正数,1代表为负数;指数位 (Exponent):用于存储科学计数法中的指数数据,...

Cookie1997的小屋 7万+

直流有刷电机控制 - 认识电机(一)

电机控制学习

u011030644的博客 917

Flink CDC 1.18.1 Oracle 数据同步到postgresql

8、修改Flink的配置文件,主要是各种服务的绑定地址,默认为localhost,统统改为0.0.0.0,如:rest.address: 0.0.0.0 #localhost。将flink-sql-connector-oracle-cdc-3.0.1.jar复制到flink-1.18.1/lib目录中。6、下载 flink-connector-jdbc-3.1.1-1.17.jar,postgresql-42.7.3.jar。7、安装postgresql就不说了,相信你已经有了数据库了。

ynzhangyao的专栏 1799

malloc的强制转换

因为数据结构课在使用malloc函数的时候一直很迷惑,为什么一定需要在前面加上一个强制转换语句,像是这样:int *a = (int *)malloc(sizeof(int)*3);。 为此我在菜鸟教程的malloc()函数介绍中找到了关于malloc的声明:void *malloc(size_t size),显然加上一个强制转换语句并不是标准语法必须的东西,但是在菜鸟教程下面的举例中是按照强制转换的写法来写的,可惜没有说为什么。为此我尝试了不加强制转换语句的malloc来直接分配空间,在gcc编译后并没有

云雾海的各种笔记 4833

云服务器安装ros教程

要在 CentOS 7 系统上安装 RouterOS,您需要将 RouterOS 安装为虚拟机或直接安装到物理硬盘上。这里提供的是将 RouterOS 安装到物理硬盘上的步骤,这将完全替换现有的 CentOS 7 系统。请确保您已经备份了所有重要数据。

qq_37662563的博客 2145

Scala类型自动转换强制转换

当Scala程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这个就是自动类型转换(隐式转换)。数据类型按精度(容量)大小排序为: (1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。 (2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。 (3)(byte,short)和char之间不会相互自动转换。 (4)byte,short,char他们三者可以计算,在计算时首先转换为int类型。

qq_39674417的博客 3747

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

指针类型的强制转换

我的改变:void和任何其他类型的指针之间可以相互转换。 int a = 1; int *p = &a; float p1 = (float)p; 则p和p1的值都是&a,但是p是将&a地址中的值按照int型变量进行解释,而p1则是将&a地址中的值按照float型变量进行解释。 指针也是一个变量,它自己占据一个4个字节的地址空间(由于程序的寻址空间是2^32次方,即...

qq_41624617的博客 9424

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C++的四种强制转换

1.背景 大家好,我是酒馆店小二。 C风格的强制转换(Type Cast)容易理解,不管什么类型的转换都可以使用使用下面的方式。 TypeName res = (NewTypeName)ans; 当然,C++也是支持C风格的强制转换,但是C风格的强制转换可能带来一些隐患,让一些问题难以察觉。所以C++提供了一组可以用在不同场合的强制转换的函数。 2.const_cast 常量转换 const_cast用于强制去掉不能被修改的常数特性,其去除常量性的对象一般为指针或引用。 用法:const_cast&lt

qq_43700779的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++强制转换重载

一、强制转换 可以使用关键字来 operator来指定强制转换使用的函数  operator来进行强制转换成int operator int()方式就可以 #include using namespace std; class A { public: A(int x) {   this->x=x; } operator int() { cout return thi

xiaoyezi1001的专栏 947

C的强制转换和C++的强制转换

C的强制转换: (type)   其中,type为类型描述符,如int,float等。为表达式。经强制类型转换运算符运算后,返回一个具有type类型的数值,这种强制类型转换操作并不改变操作数本身,运算后操作数本身未改变,例如:   int nVar=0xab65;   char cChar=char (nVar);   上述强制类型转换的结果是将整型值0xab65的高端两个字节删掉,将低端两个字

xiaodan007的专栏 2049

android类型强制转换,android中如何进行强制类型转换

匿名用户1级2012-06-21 回答Java 的自动转换如果下列2个条件都能满足,那么将一种类型的数据赋给另外一种类型变量时,将执行自动类型转换(automatic type conversion):1,这2种类型是兼容的。2,目的类型数的范围比来源类型的大。 ,当以上2个条件都满足时,拓宽转换(widening conversion )发生。例如,int 型的范围比所有byte 型的合法范围大...

weixin_28952471的博客 2217

强制类型转换

强制类型转换 /* 强制类型转换 1.特点:代码需要进行特殊的格式处理,不能自动完成。 2。格式:范围小的类型 范围小的变量名 = (范围小的类型)原本范围大的数据; 注意事项: 1.强制类型转换一般不推荐使用,因为有可能发生精度损、数据溢出。 2.byte/short/char这三种类型都可以发生数学运算,例如加法"+" 3.byte/short/char这三种类型在运算的时候,都会被首先提升为int类型,然后再计算。 4.boolean类型不能发生数据类型转换 */ public clas

AN1433223的博客 1208

如何进行强制类型转换?

如何进行强制类型转换?

shuo277的博客 5499

C++四种强制转换

四种强制类型转换

5412

html类型强制转换,C++四种强制转换

C++四种强制转换C语言的强制转换为在数据面前之间加数据类型进行转换,即(目标数据类型)原数据类型。c++为了更好的区分强制转换的类型,达到见其名知其意的效果,共将强制转换分为四种,即1、static_cast原数据类型2、const_cast原数据类型3、reinterpret_cast原数据类型4、dynamic_cast原数据类型解析static_cast<>()1)用于类层次结...

weixin_34163125的博客 323

C# 里面的强制转换

我们在平时用到数据之间的运算的时候 会遇到不同类型的数据无法相加的bug 不过 一般会有一些提示比如说 什么类型的数据无法转换成什么类型的数据 如图: 一般的数据之间的转换都遵循一个规则 当我们运算的时候 ,会从小的数据类型自动转换到大的类型 。因为编译器知道你当前的数据进行操作是否会出现数组越界;所以自动给我们转换。 我们对于这种有两种解决方法: 1:给小的数据前面加上强制转换,使得当前都为那个偏小的数据 举个栗子: float number001 = 1;

weixin_43511871的博客 5614

C++强制类型转换

c++中的类型转换

qq_54413454的博客 1733

c语言——类型的强制转换

类型转换是处理不同数据类型间交互的重要手段。当我们写下这样的代码时,就涉及到了强制类型转换。这行代码调用sqrt函数计算n的平方根,该函数返回的是double类型的值,而通过(int)的强制转换,将结果转换为int类型,直接舍弃小数部分,只保留整数部分。下面,我们将深入探讨强制类型转换的方方面面。

2301_80931230的博客 2011
上一篇: 位域的使用
下一篇: 好笑,写一个病毒
gnuser
博客等级 码龄20年 35粉丝 141原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值