【C++练级之路】【Lv.26】类型转换

07-17 136阅读


【C++练级之路】【Lv.26】类型转换


快乐的流畅:个人主页


个人专栏:《算法神殿》《数据结构世界》《进击的C++》 远方有一堆篝火,在为久候之人燃烧!

文章目录

  • 一、C风格类型转换
    • 1.1 隐式类型转换
    • 1.2 显式类型转换
    • 二、C++风格类型转换
      • 2.1 static_cast
      • 2.2 dynamic_cast
      • 2.3 const_cast
      • 2.4 reinterpret_cast
      • 三、RTTI
        • 3.1 typeid
        • 3.2 dynamic_cast
        • 3.3 decltype
        • 总结

          一、C风格类型转换

          1.1 隐式类型转换

          隐式类型转换(Implicit Type Conversion),又称自动类型转换,由编译器在编译阶段自动进行,能转就转,不能转就编译失败。

          常见的隐式类型转换包括:

          • 赋值运算符中的类型转换:例如从 int 赋值转换为 double。
          • 算术运算符中的类型转换: 例如 int 与 long 进行运算,会被提升为 long 。同时,超出类型的表示范围,会进行符号扩展或截断。
          • 函数调用中的类型转换:实参与形参类型不匹配,会尝试转换为与形参匹配的类型。
          • 布尔值中的类型转换:对于数值类型,非零值转换为 true ,零值转换为 false ;对于指针类型,非空指针转换为 true ,空指针转换为 false 。
          • 指针中的类型转换:指针可以隐式转换为 void* 类型。数组名会被转换为指向数组第一个元素的指针,函数名会被转换为指向该函数的指针。
            void func(double d){}
            void test()
            {
            	int i = 1;
            	double d = i;//赋值运算符
            	double ret = i + d;//算术运算符
            	func(i);//函数调用
            	void* p = &i;//指针
            }
            

            1.2 显式类型转换

            显式类型转换(Explicit Type Conversion),又称为强制类型转换,需要程序员显式地指定转换方式。

            格式:(type)expression

            void test()
            {
            	int i = 1;
            	double d = (double)i;
            }
            

            二、C++风格类型转换

            2.1 static_cast

            格式:static_cast(expression)

            用于非多态类型的转换(静态转换),并且只适用相近类型之间的转换,对应C的隐式类型转换,例如基本数据类型之间的转换。

            void test()
            {
            	int i = 1;
            	double d = static_cast(i);//静态转换,相近类型
            	int* pi = &i;
            	void* p = static_cast(pi);
            }
            

            2.2 dynamic_cast

            格式:dynamic_cast(expression)

            用于多态类型的转换(动态转换),并且用于向下转型:将一个父类对象的指针/引用转换为子类对象的指针或引用。

            ps:向上转型,没有类型转换,属于赋值兼容规则。

            class A
            {
            public:
            	virtual void f(){}
            	int _a = 1;
            };
            class B :public A
            {
            public:
            	virtual void f(){}
            	int _b = 2;
            };
            void test()
            {
            	B b;
            	A a = b;
            	A& ra = b;//此处没有隐式类型转换
            	double d = 3.14;
            	const int& ri = d;//此处有隐式类型转换
            }
            

            由于类型转换后的临时对象具有常性,所以要用常引用。而向上转型(切片)不用常引用,所以没有发生类型转换。


            dynamic_cast 在运行时检查转换是否有效。如果转换无效,则指针类型返回空指针 nullptr,引用类型抛出异常 std::bad_cast。

            void func(A* pa)
            {
            	//B* p = (B*)pa;//直接向下转换,如果指向父类,则存在越界风险
            	B* p = dynamic_cast(pa);
            	if (p)
            	{
            		p->_a++;
            		p->_b++;
            	}
            	else
            	{
            		cout 
            	B b;
            	A a = b;
            	func(&a);
            	func(&b);
            }
            
            	const int a = 2;
            	int* p = const_cast
            	volatile const int a = 2;
            	int* p = const_cast
            	int i = 1;
            	int* p = &i;
            	//double* p1 = static_cast
            	auto f = [](int x, int y){return x + y;};
            	cout };
            class Derive :public Base
            {};
            void func(Base* pb)
            {
            	Derive* pd = dynamic_cast
            	int x = 1;
            	double y = 2.0;
            	auto ret = x * y;
            	vector
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]