【C++】四种强制类型转换

C++中有四种强制类型转换: 静态转换:static_cast、动态转换:dynamic_cast、重新解释:reinterpret_cast、常量转换(去常性):const_cast

1.静态转换(static_cast):可以用于基本数据类型之间的转换,也可以将基类指针或引用转换为派生类指针或引用,但是转换时需要保证类型转换是安全的。静态转换不能用于去除对象的const、volatile属性

2.动态转换(dynamic_cast):主要用于将基类指针或引用转换为派生类指针引用,但是转换时需要判断类型转换是否安全,如果不安全则返回空指针。只有指向具有多态性质的类的基类指针或引用才能使用dynamic_cast。

3.重新解释转换(reinterpret_cast):将一个指针或引用转换为一个与其类型无关的指针或引用。这种转换不会进行类型检查,因此很容易引发未定义的行为,应该避免使用。

4.常量转换(const_cast):用于去除一个变量或指针的const、volatile属性。这种转换也需要谨慎使用,因为去除const属性可能会导致未定义的行为。


 static_cast

static_cast<目的类型>(表达式)

1.基本数据类型之间的转换

{
	int a = 5;
	float b = 2.2;
	//printf("%f\n", a);//错误输出
	//printf("%d\n", b);//错误输出
	printf("%f\n", (float)a);
	printf("%d\n", (int)b);
	
	a = static_cast<int>(b);//c++的强转
}

2.枚举类型之间的转换

int main()
{
	enum AA{A = 3,B = 10};
	enum BB{C = 5,D = 30};
	int a = 20;
	enum AA aa = A;
	cout << aa << endl;
	//aa = a;//枚举类型的只能用枚举类型内的赋值
	aa = static_cast<enum AA>(a);
	cout << aa << endl;

	enum BB bb = C;
	aa = static_cast<enum AA>(bb);
}

3.指针类型转换成void*

int main()
{
	int a = 10;
	int* p = nullptr;
	char ch = 'a';
	void* vp = &a;
	p = static_cast<int*>(vp);
	cout << *p << endl;

	//不安全--两边解析的大小不同
	vp = &ch;
	p = static_cast<int*>(vp);
	cout << *p << endl;
}

4.将一个变量转换成常量

        这种不用强转其实也可以

int main()
{
	int a = 20;
	const int ca = a;
	const int cb = static_cast<const int>(a);
	cout << ca << endl;
}

5.基类和派生类之间的转换--没有virtual

class A
{
public:
	void fn() { cout << "A::fn" << endl; }
	void gn() { cout << "A::gn" << endl; }
};
class B :public A
{
public:
	void fn() { cout << "B::fn" << endl; }//隐藏,没有虚
	void hn() { cout << "B::hn" << endl; }
};
int main()
{
	A a;
	B b;
	A* pa = &b;
	pa->fn();//A
	pa->gn();//A
//	B* pb = &a;//error
	B* pb = static_cast<B*>(&a);
	pb->fn();//B
	pb->gn();//A
	pb->hn();//B
	pb->A::fn();//A
}

6.没有关系的类之间的转换

class A
{
public:
	void fn() { cout << "A::fn" << endl; }
};
class B
{
public:
	B(A&a){}//构造函数可以进行强转
	void gn() { cout << "B::gn" << endl; }
};
int main()
{
	A a;
	B b = static_cast<B>(a);//B b(a);
	b.gn();
}

dynamic_cast

        将基类的指针或引用安全的转换为派生类的指针或引用,并用派生类的指针或引用来调用非虚函数。
注意:当使用dynamic_cast时,该类型要包含有虚函数,才能进行转换,否则错误。

class A
{
public:
	void print() { cout << "A::print" << endl; }
	virtual ~A() {};//多态
};
class B :public A
{
public:
	void show() 
	{
		cout << "B::show" << endl;
	}
};
int main()
{
	A* pa = new A;
	B* pb = dynamic_cast<B*>(pa);
	pb->print();
	pb->show();
}

reinterpret_cast

        适用于指针转换为另一种指针,转化不用修改指针变量值数据存储格式,不改变指针变量的值,只需要在编译时重新解释指针的类型即可。也可以将指针,直接转化成整形值。

int main1()
{
	float ff = 3.5f;
	float* pf = &ff;
	int* pi = reinterpret_cast<int*>(pf);//编译时重新解释
	cout << *pi << endl;//取不到正确的值
	cout << *pf << endl;//pf不变

	//整形按二进制补码存
	unsigned int a = -2;//把-2放到a开辟的空间中
	/*
	00000000 00000000 00000000 00000010
	11111111 11111111 11111111 11111110:-2,4294967294
	unsigned无符号位
	*/
	//浮点sem存
}

class A
{

};
class B
{

};
int main()
{
	A* pa = new A;
	B* pb = reinterpret_cast<B*>(pa);
	//B*pb = (B*)pa;
	int a = 10;
	int* pi = &a;
	long j = reinterpret_cast<long>(pi);
	cout << j << endl;//地址值
}

const_cast

static_cast不能移除变量的const属性,const_cast可以,但是就算可以强转了const在数据区的内容也不改变。

int main()
{
    const int cb = 10;
    //int* p = &cb;
    //int* p = static_cast<int*>(&cb);//error
    int* p = const_cast<int*>(&cb);//
    *p = 30;
    cout << cb << endl;//cb在字符串常量区,改不了,输出10
}

  • 10
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在C/C++语言中,用(type) value(在C还可以采用type(value))来进行显式类型转换(explicit type conversion),常常被称为强制转换(cast投射/铸模)。强制转换在C程序中被过度使用,成为程序错误的一个主要原因。为了减少强制转换的副作用,并使程序员能够快速定位强制转换的错误,在标准C中新增了4个关键字*_cast,用来提倡一种全新的C显式转换语法。 其中,强制转换关键字包括: 1. static_cast(静态转换):用于明确定义良性和适度良性的转换,包括原来不需要采用强制转换的自动类型转换(包括无损的提升转换和可能丢失信息的窄化转换)。标准C提倡对任何数据的类型转换都采用static_cast显式类型转换方法。 2. const_cast(常量转换):可将(同数据类型的)常型(const)转换为非常型、将易变(volatile)型转换为非易变型。如果用于其他类型的转换,一般会产生一个编译错误。 3. reinterpret_cast(重新解释转换):用于将一个指针或引用转换为其他类型的指针或引用,甚至不同类型之间的指针或引用,但是这种转换是最危险的,因为它会绕过编译器的类型检查。 4. dynamic_cast(动态转换):用于在继承关系中进行类型转换,用于将基类指针或引用转换为派生类指针或引用,但是这种转换只能在运行时进行,并且只能用于具有虚函数的类。 以上是C/C++中的强制转换关键字。它们提供了不同的转换功能,程序员应根据具体情况选择合适的关键字来进行类型转换。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曦樂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值