首页 > 编程学习 > C++--类型转换--1128

C++--类型转换--1128

发布时间:2022/12/10 17:48:29

1.C语言中的类型转换

分为隐式类型转化、显示强制类型转化。

隐式类型转化用于意义相近的类型,比如int,double,short都是表示数值的类型

 int i=1; double d=i;  //编译、结果无问题  这里是隐式类型转换。

显示强制类型转换

显示强制类型用于意义不相近的类型,比如地址和int

int *p=&i;  int address=(int) p;//使用显示强制类型转换时编译、结果才无问题。

 缺陷:转换的可视性差,所有类型转换的形式都是一种相同形式,错误难以排查。

2.C++的类型转换

标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符。

static_cast          reinterpret_cast        const_cast         dynamic_cast

2.1 static_cast

static_cast 用于非多态类型的转换(静态转换)。编译器隐式执行的任何类型转换都可以用static_cast(用于意义相近的类型,不相关的类型用会报错)

int main()
{double d=23.14;int a=static_cast<int>(d);cout<<a<<endl;return 0;
}

2.2 reinterpret_cast

不相关类型的转换

int main()
{double d = 23.14;int a = static_cast<int>(d);int* p = reinterpret_cast<int*>(a);//将一个表示数值的整形变成了地址return 0;
}

2.3 const_cast

删除变量的const属性,方便赋值。

int main()
{const int a = 2;int* p = const_cast<int*>(&a);//const int* 转换成了int**p = 3;cout << a << endl << *p << endl;return 0;
}

 为什么我们在监视窗口确实看到了a的值被修改成了3,而最终结果仍然是2呢?

这里是编译器的一些优化,有些编译器会将const变量直接放在寄存器中,需要使用a的时候直接从寄存器拿,而调试相当于另一个进程,自然不会影响我们主进程的结果。有些编译器(VS)会将const变量声明成宏的形式,在使用的时候直接输出结果而不是变量值。

 2.4 dynamic_cast

用于将一个父类对象的指针和引用转换为子类对象的指针或引用。(动态转换)

向上转型:子类对象指针/引用 转换为父类对象指针/引用 (不需要转换,赋值兼容规则,切片)

向下转型:父类对象指针/引用 转子类 (用dynamic_cast转型是安全的)

注意

dynamic_cast只能用于父类中含有虚函数的类。

dynamic_cast会先检查是否能转换成功,能成功就转换,不能返回0

class a
{
public:virtual void f(){}
public:int _a = 0;
};class b : public a
{
public:int _b = 1;
};// a*指针pa有可能指向父类,有可能指向子类
void fun(a* pa)
{// 如果pa是指向子类,那么可以转换,转换表达式返回正确的地址// 如果pa是指向父类,那么不能转换,转换表达式返回nullptrb* pb = dynamic_cast<b*>(pa); // 安全的//b* pb = (b*)pa;             // 不安全if (pb){cout << "转换成功" << endl;pb->_a++;pb->_b++;cout << pb->_a << ":" << pb->_b << endl;}else{cout << "转换失败" << endl;pa->_a++;cout << pa->_a << endl;}
}
int main()
{a aa;// 父类对象无论如何都是不允许转换成子类对象的/*b bb = dynamic_cast<b>(aa);b bb = (b)aa;*/b bb;fun(&aa);fun(&bb);//fun(nullptr);return 0;
}

2.4.2 dynamic_cast的意义

如果我们仍然使用C语言中的强制类型转换,不论我传入的pa是子类指针还是父类指针,结果就会都是转换成功。并且当我传入的是父类指针时,解引用出现错误,导致程序终止。

2.4.3 dynamic_cast和强制类型转换的多继承

class A1
{
public:virtual void f(){}
public:int _a1 = 0;
};class A2
{
public:virtual void f(){}
public:int _a2 = 0;
};class B : public A1, public A2
{
public:int _b = 1;
};

 注意强制类型转换也会让指针偏移回去,在这里和dynamic_cast结果是一样的

 

 

 

 

 


本文链接:https://www.ngui.cc/article/show-747563.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000