c++中的类型转换

来源:互联网 发布:域名运营商查询 编辑:程序博客网 时间:2024/06/07 22:27

关于强制类型转换,在c语言中我们就知道有显式类型转换和隐式类型转换,在前边的博

客《数字的奇妙世界》中有提到,这里就不说了,只讲c++中的强制类型转换。

c++中的强制类型转换有以下四种方式:

static_cast/reinterpret_cast/const_cast/dynamic_cast

static_cast用于静态转换,但是不可用于不相关类型之间的转换。

看下边的代码:

void test(){int m = 5;double d = static_cast<double> (m);//正确cout << d << endl;int *p = static_cast<int *>(m);//错误,static_cast不可用于不相关类型的转换}


reinterpret_cast用于不相关类型之间的转换。举例:

void test1(){int m = 5;int *p = reinterpret_cast<int *>(m);//正确double d = reinterpret_cast<double> (m);//错误,reinterpret_cast不可用于相关类型的转换}


再看下边的例子:

typedef void(*Func) ();int DoSomething(){cout << "DoSomething" << endl;return 0;}void test(){Func f = reinterpret_cast<Func>(DoSomething);f();}


上边的代码,DoSomething可以被调用,只是一般不那么做。

const_cast:去掉常属性。

const int a = 10;int *pa = &a;


我们知道,上边的这段代码是不正确的。非常量指针不能指向常量变量。

然而,我们可以通过const_cast完成转换。举例如下:

void test(){const int a = 10;int *pa = const_cast<int*> (&a);*pa = 100;cout << a << endl;cout << *pa << endl;}


上边的代码输出a为10,*pa为100.*pa为100这是显而易见的。那么a为什么还是10呢?

这是因为,常量a被存入寄存器,寄存器中的值一直未被改,改的只是内存中的值。要

是我们在const int a = 10;前边加上关键字volatile,输出的a就是100.关键字volatile表明

每次读取a时,是在内存中读取。也就是保证内存的可见性

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

转换)

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

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

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

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

看下边的实例:

class B{public:virtual void f(){}};class D :public B{virtual void f(){}};void test(){D d;B b;D *pd = dynamic_cast<D*>(&b);cout << pd << endl;//0B* pb = &b;pd = dynamic_cast<D*>(pb);cout << pd << endl;//0pb = &d;pd = dynamic_cast<D*>(pb);cout << pd << endl;//非0}


恩,dynamic_cast是用于父类指针转为子类指针。如果父类指针指向父类对象,转换失

败(返回0),如果父类指针指向子类对象,返回转换后的地址。

explicit关键字:


explicit关键字是为了阻止构造函数定义的隐式转换。举例:

class A{public:A(int a = 0):m_a(a){}void fun(A a){cout << "hello" << endl;}private:int m_a;};int main(){A a;a.fun(10);system("pause");return 0;}



这样可以成功输出hello,是因为编译器做了优化(用实参10构造出一个A类对象出

来)。如果在类内部构造函数前边加上explicit关键字,程序报错。此时抑制了编译器的

优化,当然我们也可以显式将fun的实参转换成对象,即就是a.fun(A(10));


注意:类外定义的构造函数不能加explicit关键字;explicit关键字只对一个参数的构造函

数有效。


不去整理,不去思考,永远不知道自己哪里还不懂~~~

0 0
原创粉丝点击