您的位置:首页 > 编程语言 > C语言/C++

C++ 四种类型转换

2016-04-05 10:44 525 查看

C++ 四种类型转换

<span style="font-size:18px;"><span style="font-size:18px;">#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*
static_cast:
用法:static_cast < type-id > ( expression )

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。static_cast
static_cast

进行上行转换(把派生类的指针或引用转换成基类表示,对象也可以)是安全的;

进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,无任何效果

②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。

③把空指针转换成目标类型的空指针。

④把任何类型的表达式转换成void类型。
*/

/*
dynamic_cast:
用法:dynamic_cast < type-id > ( expression )
type-id 必须是个多态类型,即必须要含有虚函数,类中有虚表才能存储 运行时类别信息。
该运算符把expression转换成type - id类型的对象。Type - id必须是类的指针、类的引用或者void*;

如果type - id是类指针类型,那么expression也必须是一个指针,如果type - id是一个引用,那么expression也必须是一个引用。

dynamic_cast运算符可以在执行期决定真正的类型。如果downcast是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果downcast不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;

在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
*/
/*
const_cast
用法:const_cast < type-id > ( expression )
该操作符用于改变const和volatile,const_cast最常用的用途就是删除const属性,如果某个变量在大多数时候是常量,而在某个时候又是需要修改的,这时就可以使用const_cast操作符了。但是不能改变其值类型,只能改变属性。
*/

/*
reinterpret_cast<type-id> (expression)
type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。
操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。
reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。(这句话是C++编程思想中的原话)
*/
class X
{
public:
virtual void Print()
{
puts("X");
}
};

class A :public X
{
public:
virtual void Print()
{
puts("A");
}
};

class B :public X
{
public:
virtual void Print()
{
puts("B");
}
};

/*
X
/ \
A  B

*/
class F
{
public:
virtual void Print()
{
puts("F");
}
};

class G:public F
{
public:
virtual void Print()
{
puts("G");
}
};

int main(void)
{
X x;
A a;
B b;
F f;
G g;
X* px =nullptr;
A* pa = nullptr;
B* pb = nullptr;
F* pf = nullptr;
G* pg = nullptr;

puts("----------static_cast---------------");
int i1 = 0;
double dou1 = 3.66;
cout << "i1: " << static_cast<int>(dou1)<<endl;
//多态 子类向父类转换
px = static_cast<X*>(&a);
px->Print();//A

//非多态 子类向父类转换
pg = static_cast<G*>(&f);
pg->Print();//F

//多态 父类向子类转换(无任何作用)
pa = static_cast<A*>(&x);
pa->Print();//X

//非多态 父类向子类转换(无任何作用)
pa = static_cast<A*>(&x);
pa->Print();//X

//多态 子类向父类转换(无任何作用)
pf = static_cast<F*>(&g);
pa->Print();//X

//不相关类类型强转(无任何作用)
pa = (A*)(&b);
pa->Print();
//pa = static_cast<A*>(&b); 不相关自定义类型转换(报错)
x = static_cast<X>(a);
x.Print();//B
puts("----------dynamic_cast---------------");
//pa->Print();  pa指向了B 转换之后也是指向B
px = dynamic_cast<X*>(pa);
if (nullptr != px)
{
px->Print();//B
}
pa = dynamic_cast<A*>(px);//得到空指针
if (nullptr != pa)
{
pa->Print();
}

A a1;
A& refA = a1;
X& refX = dynamic_cast<X&>(a1);
refX.Print();// A 反过来会产生异常

puts("----------const_cast---------------");

char c = 'A';
int k = 1;
char* pC = reinterpret_cast<char*>(&k);
short* pS= reinterpret_cast<short*>(&k);
printf("char*   %p\n", &c);
printf("int*:   %p\n",&k);
printf("reinterpret_cast char*%p\n",pC);
printf("reinterpret_cast short*:%p\n", pS);

printf("char*   %p\n", &c+1);
printf("int*:   %p\n", &k+1);
printf("reinterpret_cast char*%p\n", pC+1);
printf("reinterpret_cast short*:%p\n", pS+1);
int* p1 = &k;
printf("int*:   %d\n", p1);
++p1;
printf("int*:   %d\n", p1);
p1 = reinterpret_cast<int*>('A');
cout << p1 << endl;//00000041 将一个整数转换为指针
char ch = (char)(p1);
cout << ch << endl;//A  再转换回来可以得到同样的值

return 0;
}</span></span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: