C++的强制转换

C中的强制转换

   在C语言中的强制转换为如下面所示:

short b=1;
int a=(int)b;
int a=int(b);

//******************************************
// class type-casting
#include <iostream>
using namespace std;

class CDummy {
float i,j;
CDummy():i(100),j(10){}
};

class CAddition:public CDummy
{
    int *x,y;
  public:
    CAddition (int a, int b) { x=&a; y=b; }
    int result() { return *x+y;}
};

int main () {
  CDummy d;
  CAddition * padd;
  padd = (CAddition*) &d;
  cout << padd->result();
  return 0;
}

第一个是强制类型的数字类型转换,当小范围向大范围转换是可以隐式的转换,如果是大范围向小范围转换就需要强制类型转换会有waring。就需要前面的两种方式。同样的,如果是类的话,可以将指向子类的指针,指向父类的对象,将父类的对象强制转换为子类的指针。但是这样的话,可能会出现问题,就是实际并不能调用子类的函数等。如果是指向父类的指针指向将子类的对象,是没有问题的。

这个时候C语言中的强制类型转换并没有做出任何的安全提示。


C++中提供了四种强制类型转换的方式

  • const_casr<new_type>(expression)
  • static_cast <new_type> (expression)
  • reinterpret_cast <new_type> (expression)
  • dynamic_cast <new_type> (expression)

下面一个个的简单的将一下,我也可看到别人的文章的。

const_casr<new_type>(expression)

第一是,将常量的的类型转换为非常量的。详情可以看:https://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html

const int constant = 21;
const int* const_p = &constant;
int* modifier = const_cast<int*>(&constant);

虽然,这个三个的变量的地址或者是指针指向的地址是一样,但是其实你如果修改了modifier指向的值的话,constant的值其实还是没呀改变的。这中行为是一种未定义的行为。是不推荐的使用的,这种常量转换的应用场合是:第一个,就是我们需要使用一个函数,这个函数的参数变量是非常量的,但是实际上我们传入的参数是常量的,这个时候就需要进行类型转换。转换为非常量的。或者说一个const的对象要调用一个非const的方法,所以需要进行类型转换。

#include <iostream>
using namespace std;

void Printer (int* val,string seperator = "\n")
{
	cout << val<< seperator;
}

int main(void) 
{	
	const int consatant = 20;
	//Printer(consatant);//Error: invalid conversion from 'int' to 'int*'
	Printer(const_cast<int *>(&consatant));
	
	return 0;
}

第二种就是, 用一个const的类型的数据,对一个变量进行了赋值或者是初始化,我们要修改,就可以用类型转换

#include <iostream>
using namespace std;

int main(void) {
	int variable = 21;
	int* const_p = &variable;
	int* modifier = const_cast<int*>(const_p);
	
	*modifier = 7
	cout << "variable:" << variable << endl;
	
	return 0;
}


static_cast <new_type> (expression)

这个基本上是和C的强制类型转换,一样是,是可以将两个不同的类型的指针进行强制转换,甚至是可以不讲道理

// class type-casting
#include <iostream>
using namespace std;

class CDummy {
    float i,j;
};

class CAddition {
    int x,y;
  public:
    CAddition (int a, int b) { x=a; y=b; }
    int result() { return x+y;}
};

int main () {
  CDummy d;
  CAddition * padd;
  padd = (CAddition*) &d;
  cout << padd->result();
  return 0;
}

比如说这个,两个不同的类型的指针都可以强制转换,不讲道理。


 reinterpret_cast <new_type> (expression)

这个更加的不讲道理,也是任何两个类型之间的都可以强行转换,更加不讲道理的是,这个还可以将整数的类型转换为指针,或者是将指针转换为整数的类型。非常的底层很硬核,简直是丧心病狂。

class A {};

A * a = new A;

int B = reinterpret_cast<B*>(a);//correct!

dynamic_cast <new_type> (expression)

     动态转换确保类指针的转换是合适完整的,它有两个重要的约束条件,其一是要求new_type为指针或引用,其二是下行转换时要求基类是多态的(基类中包含至少一个虚函数)。

所谓的下行转换。“下”表示沿着继承链向下走(向子类的方向走)。

类似地,上行转换的“上”表示沿继承链向上走(向父类的方向走)。

我们给出结论,上行转换一般是安全的,下行转换很可能是不安全的。

为什么呢?因为子类中包含父类,所以上行转换(只能调用父类的方法,引用父类的成员变量)一般是安全的。但父类中却没有子类的任何信息,而下行转换会调用到子类的方法、引用子类的成员变量,这些父类都没有,所以很容易“指鹿为马”或者干脆指向不存在的内存空间。

#include <iostream>
using namespace std;
class CBase { };

class CDerived: public CBase {};

int main()
{
CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived 
}

比如这样的转换就是,不可以的,因为子类不是多态的。 

#include <iostream>
using namespace std;
class CBase { virtual void dummy() {} };

class CDerived: public CBase {};

int main()
{
CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b);  // ok
}

这个编译是没有问题,但是pd的值会是零。也就是说不安全的下行转换,并不会抛出异常,只是将返回的值修改为0.。

一个特例是void *的指针,总是被认为是安全的,但是要必须是多态的。

#include <iostream>
using namespace std;
class A {virtual void f(){}};
class B {virtual void f(){}};

int main() {
    A* pa = new A;
    B* pb = new B;
    void* pv = dynamic_cast<void*>(pa);
    cout << pv << endl;
    // pv now points to an object of type A

    pv = dynamic_cast<void*>(pb);
    cout << pv << endl;
    // pv now points to an object of type B
}

这个参考的文章是:https://blog.csdn.net/chenlycly/article/details/38713981

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值