注册网站流程及资料,优化师,成都装修公司一览表,网站建设jiq目录
static_cast#xff1a;static_cast(expression)
const_cast
dynamic_cast
reinterpret_cast C 提供以下几类转换
static_cast#xff1a;static_casttype-id(expression)
tatic_cast 主要用于以下几种情况#xff1a;
用于显式地将一个表达式转换为另一…目录
static_caststatic_cast(expression)
const_cast
dynamic_cast
reinterpret_cast C 提供以下几类转换
static_caststatic_casttype-id(expression)
tatic_cast 主要用于以下几种情况
用于显式地将一个表达式转换为另一种类型包括基本类型、指针类型和引用类型。用于将基类指针或引用转换为派生类指针或引用向下转型。用于将 void* 指针转换为任意类型的指针。用于将任意类型的指针转换为 void* 指针。
需要注意的是tatic_cast 不会在运行时检查该对象的运行时类型安全的向下转换可以用dynamic_cast 执行
示例
#include vector
#include iostreamstruct B
{int m 0;void hello() const{std::cout Hello world这里是 B\n;}
};struct D : B
{void hello() const{std::cout Hello world这里是 D\n;}
};enum class E { ONE 1, TWO, THREE };
enum EU { ONE 1, TWO, THREE };int main()
{// 1: 静态向下转型D d;B br d; // 通过隐式转换向上转型br.hello();D another_d static_castD(br); // 向下转型another_d.hello();// 2: 左值到右值std::vectorint v2 static_caststd::vectorint(v);std::cout 移动后v.size() v.size() \n;// 3: 初始化转换int n static_castint(3.14); std::cout n n \n;std::vectorint v static_caststd::vectorint(10);std::cout v.size() v.size() \n;// 4: 弃值表达式static_castvoid(v2.size());// 5. 隐式转换的逆转换void* nv n;int* ni static_castint*(nv);std::cout *ni *ni \n;// 6. 数组到指针后随向上转型D a[10];B* dp static_castB*(a);// 7. 有作用域枚举到 int 或 floatE e E::ONE;int one static_castint(e);std::cout one \n;// 8. int 到枚举枚举到另一枚举E e2 static_castE(one);EU eu static_castEU(e2);// 9. 指向成员指针向上转型int D::*pm D::m;std::cout br.*static_castint B::*(pm) \n;// 10. void* 到任何类型void* voidp e;std::vectorint* p static_caststd::vectorint*(voidp);
}
输出 Hello world这里是 B
Hello world这里是 D
移动后v.size() 0
n 3
v.size() 10
*ni 3
1
0 const_cast 类型转换运算符可以将 const 和 volatile 限定符从指针或引用类型中去除。它可以用于将常量对象变成非常量对象从而允许对其进行修改函数指针和成员函数指针无法用于 const_cast 示例
#include iostreamstruct type
{int i;type(): i(3) {}void f(int v) const {// this-i v; // 编译错误this 是指向 const 的指针const_casttype*(this)-i v; // 只要该对象不是 const 就 OK}
};int main()
{int i 3; // 不声明 i 为 constconst int rci i; const_castint(rci) 4; // OK修改 istd::cout i i \n;type t; // 如果这是 const type t那么 t.f(4) 会是未定义行为t.f(4);std::cout type::i t.i \n;const int j 3; // 声明 j 为 const[[maybe_unused]] //可能是有意不使用,编译器不会发出警告int* pj const_castint*(j);// *pj 4; // 未定义行为[[maybe_unused]]void (type::* pmf)(int) const type::f; // 指向成员函数的指针// const_castvoid(type::*)(int)(pmf); // 编译错误const_cast 不能用于成员函数指针
}
dynamic_cast
沿继承层级向上、向下及侧向安全地转换到其他类的指针和引用失败会返回空指针
#include iostreamstruct V
{virtual void f() {} // 必须为多态以使用运行时检查的 dynamic_cast
};struct A : virtual V {};struct B : virtual V
{B(V* v, A* a){// 构造中转型见后述 D 的构造函数中的调用dynamic_castB*(v); // 良好定义v 有类型 V*V 是 B 的基类产生 B*dynamic_castB*(a); // 未定义行为a 有类型 A*A 不是 B 的基类}
};struct D : A, B
{D() : B(static_castA*(this), this) {}
};struct Base
{virtual ~Base() {}
};struct Derived: Base
{virtual void name() {}
};int main()
{D d; // 最终派生对象A a d; // 向上转型可以用 dynamic_cast但不是必须的[[maybe_unused]]D new_d dynamic_castD(a); // 向下转型[[maybe_unused]]B new_b dynamic_castB(a); // 侧向转型Base* b1 new Base;if (Derived* d dynamic_castDerived*(b1); d ! nullptr){std::cout 成功从 b1 向下转型到 d\n;d-name(); // 可以安全调用}Base* b2 new Derived;if (Derived* d dynamic_castDerived*(b2); d ! nullptr){std::cout 成功从 b2 向下转型到 d\n;d-name(); // 可以安全调用}delete b1;delete b2;
}
reinterpret_cast
重新解释底层位模式在类型间任意转换实际上转换比static_cast更不安全
static_cast就是利用C类型之间的继承关系图和聚合关系图编译器必须知道根据一个子对象地址计算另一个子对象的地址。
reinterpret_cast不关心继承关系直接把数据类型A的地址解释成另一个数据类型B的地址 示例
#include cstdint
#include cassert
#include iostreamint f() { return 42; }int main()
{int i 7;// 指针到整数并转回std::uintptr_t v1 reinterpret_caststd::uintptr_t(i); // 不能误用 static_caststd::cout i 的值是 std::showbase std::hex v1 \n;int* p1 reinterpret_castint*(v1);assert(p1 i);// 到另一函数指针并转回void(*fp1)() reinterpret_castvoid(*)()(f);// fp1(); 未定义行为int(*fp2)() reinterpret_castint(*)()(fp1);std::cout std::dec fp2() \n; // 安全// 通过指针的类型别名化char* p2 reinterpret_castchar*(i);std::cout (p2[0] \x7 ? 本系统是小端的\n: 本系统是大端的\n);// 通过引用的类型别名化reinterpret_castunsigned int(i) 42;std::cout i \n;[[maybe_unused]] const int const_iref i;// int iref reinterpret_castint(const_iref); // 编译错误——不能去除 const// 必须用 const_cast 代替int iref const_castint(const_iref);
}