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

### C++ 强制类型转换概述 C++ 提供了四种类型的强制类型转换操作符,分别是 `static_cast`、`const_cast`、`reinterpret_cast` 和 `dynamic_cast`。每种类型转换都有其特定的应用场景和语法规则。 --- #### 1. **`static_cast` 的使用方法** `static_cast` 是一种通用的类型转换方式,主要用于兼容编译器可以隐式完成的类型转换[^1]。它适用于以下情况: - 基本数据类型之间的转换(如 int 转 float) - 枚举类型到整数类型的转换 - 指针或引用在继承层次结构中的向上转型 ##### 示例代码: ```cpp #include &lt;iostream&gt; using namespace std; int main() { double d = 3.14; int i = static_cast&lt;int&gt;(d); // 将 double 类型转为 int 类型 cout &lt;&lt; &quot;i: &quot; &lt;&lt; i &lt;&lt; endl; void* ptr = new int(10); int* p = static_cast&lt;int*&gt;(ptr); // 将 void* 转换为具体指针类型 cout &lt;&lt; &quot;*p: &quot; &lt;&lt; *p &lt;&lt; endl; delete p; return 0; } ``` --- #### 2. **`const_cast` 的使用方法** `const_cast` 主要用于移除变量的 `const` 或 `volatile` 属性[^2]。需要注意的是,如果尝试修改原本声明为 `const` 的对象,则会导致未定义行为。 ##### 示例代码: ```cpp #include &lt;iostream&gt; using namespace std; void modify(int* p) { (*p)++; } int main() { const int a = 10; int* b = const_cast&lt;int*&gt;(&amp;a); // 移除常量属性 modify(b); cout &lt;&lt; &quot;Modified value of &#39;b&#39;: &quot; &lt;&lt; *b &lt;&lt; endl; // 输出可能不一致,因为原对象是 const return 0; } ``` --- #### 3. **`dynamic_cast` 的使用方法** `dynamic_cast` 主要在多态情况下用于安全地执行向下转型(downcasting)。只有当基类具有虚函数时才能生效,并且运行时会检查转换的有效性。如果失败,在指针上返回 `nullptr`;对于引用抛出异常。 ##### 示例代码: ```cpp class Base { public: virtual ~Base() {} }; class Derived : public Base {}; int main() { Base* basePtr = new Derived(); Derived* derivedPtr = dynamic_cast&lt;Derived*&gt;(basePtr); if (derivedPtr != nullptr) { cout &lt;&lt; &quot;Dynamic cast succeeded!&quot; &lt;&lt; endl; } else { cout &lt;&lt; &quot;Dynamic cast failed.&quot; &lt;&lt; endl; } delete basePtr; return 0; } ``` --- #### 4. **`reinterpret_cast` 的使用方法** `reinterpret_cast` 实现低级重新解释位模式的功能,通常用来将一个指针类型转换成另一个完全无关的指针类型或者整数类型。这种转换非常危险,应谨慎使用。 ##### 示例代码: ```cpp #include &lt;iostream&gt; using namespace std; int main() { int num = 42; void* vptr = &amp;num; long rawMemory = reinterpret_cast&lt;long&gt;(vptr); // 把地址当作原始内存处理 cout &lt;&lt; &quot;Raw memory address as integer: &quot; &lt;&lt; rawMemory &lt;&lt; endl; return 0; } ``` --- ### 总结 以上介绍了 C++ 中四种主要的强制类型转换及其典型应用场景。合理选用这些工具能够帮助开发者更精确地控制程序的行为,但也需注意滥用可能导致难以调试的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值