我们都知道C语言中也有类型转换,常见的有两种,一种是默认转换,例如从int类型的数据转换为一个float类型的数据,这样是可以成功的;另外一种是强制转换,这也是我们非常熟悉的操作,这里也就不多说了。
这篇文章主要介绍C++boost库中的四种类型转换:
const_cast
说明:
这个类型转化操作传递对象的const属性,或者是设置或者是移除。
用法:
const_cast< typeid>(表达式)
例如:
class C
{};
const C*a = new C;
C*b = const_cast<C*>(a);
或者
C*t = new C(&str_c);
const C* tp = const_cast<const C*>(t);
//或者栈上的对象
C cp(&str);
const C* ct = const_cast<const C*>(&cp);
测试用例
#include<iostream>
#include<string>
using namespace std;
class CP
{
public:
CP(string *str = NULL)
{
cout<<"CP(char*str = NULL)"<<endl;
_str = str;
}
void show()
{
cout<<*_str<<endl;
}
void change(string *str = NULL)
{
_str = str;
}
private:
string *_str;
};
int main()
{
string str = "hehe";
string str_c = "change world";
const CP *c = new CP(&str);
CP* d = const_cast<CP*>(c);
d->show();
d->change(&str_c);
d->show();
return 0;
}
结果
static_cast
说明
①用于类层次中基类和派生类指针或者引用的转换且遵循把派生类指针或者引用转换为基类的是安全的,反之不安全;
②用于基本类型之间的转换;
③把任何类型转换为void类型。
用法
static_cast< typeid>(表达式);
例如:
string str = "hello";
Derive * de = new Derive(10,&str);//派生类对象
Base * ba = static_cast<Base*>(de);//基类指针
或者
int *p = NULL;
void *ptr = static_cast<void*>(p);
测试用例
#include<iostream>
#include<string>
using namespace std;
class Base
{
public:
Base(string *str = NULL)
{
cout<<"Base(string*str = NULL)"<<endl;
_str = str;
}
void show()
{
cout<<*_str<<endl;
}
private:
string * _str;
};
class Derive : public Base
{
public:
Derive(int data = 0,string* str = NULL):_data(data),Base(str)
{
cout<<"Derive(int data = 0,string *str = NULL)"<<endl;
}
void show()
{
cout<<_data<<endl;
}
private:
int _data;
};
int main()
{
string str = "hello";
Derive * de = new Derive(10,&str);
Base * ba = static_cast<Base*>(de);
return 0;
}
结果
reinterpret_cast
说明
转换一个指针为其它类型,也允许一个指针转换为整数类型,在类型之间指向的内容不做任何检查或者替换,属于强转,不安全。
用法
int *p = NULL;
void *ptr = reinterpret_cast<void*>(p);
因为这种类型转换很简单就不做测试用例了。
dynamic_cast
说明
把表达式转换为typeid的类型的对象。typeid必须是类的指针、引用或者void*,一般情况下dynamic_cast用于多态性的类,即有虚函数的类的类型转换。
dynamic_cast依赖于RTTI信息,如果无法判断一个基类指针变量所指对象的真实类型,这时候只能做安全转换,即派生类指针指向基类指针。
对于上行转换(派生类对象指针或者引用转换为基类指针或者引用),dynamic_cast和static_cast是一样的。
对于下行转换,说到下行转换,有一点需要了解的是在C++中,一般是可以用父类指针指向一个子类对象,但这个指针只能访问父类定义的数据成员和函数,这是C++中的静态绑定,但一般不定义指向父类对象的子类类型指针。
在上行转换中,static_cast和dynamic_cast效果是一样的,而且都比较安全,因为向上转换的对象一般是指向子类对象的子类类型指针;而在下行转换中,static_cast只是在编译时进行类型检查,而dynamic_cast是运行时类型检查。
用法同static_cast
测试用例
#include<iostream>
#include<string>
using namespace std;
class Base
{
public:
Base(int data = 0):_data(data){cout<<"Base(int data = 0)"<<endl;}
~Base(){cout<<"~Base()"<<endl;}
virtual void show()
{
cout<<"Base::show()"<<endl;
}
private:
int _data;
};
class Derive:public Base
{
public:
Derive(int data = 0):_db(data),Base(data)
{
cout<<"Derive(int data = 0)"<<endl;
}
~Derive(){cout<<"~Derive()"<<endl;}
void show()
{
cout<<"Derive::show()"<<endl;
}
private:
int _db;
};
int main()
{//上行转换
Derive * de = new Derive(10);
Base * ba = dynamic_cast<Base*>(de);
ba->show();
Base * db = static_cast<Base*>(de);
db->show();
return 0;
}
结果
暂时就这么多吧,继续前进!