Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14843
  • 博文数量: 11
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-08 14:28
文章分类

全部博文(11)

文章存档

2013年(11)

我的朋友

分类: C/C++

2013-08-21 15:27:11

statoc_cast:
该操作符用于非多态类型的转换,任何标准转换都可以使用他,即static_cast可以把int转换为 double,但不能把两个不相关的类对象进行转换,比如类A不能转换为一个不相关的类B类型。static_cast本质上是传统c语言强制转换的替代 品。
两种不合法:
1.
char* p=new char[5];
unsigned long l=static_cast(p);  //Error : cannot convert from 'char *' to 'unsigned long' 
2. 
class A{};
A a;
unsigned long l=static_cast(a);  //Error :'static_cast' : cannot convert from 'A' to 'unsigned long'

const_cast:
可以将const类型转换为非const,也可以将非const转换为const;可以将volatile转换成非volatile,也可以将非volatile转换成volatile。
const_cast多用于指针,存在以下情况:
1. 
const int x=1;
int* p=&x;                                                      //Error : 'initializing' : cannot convert from 'const int *' to 'int *'
2.
const int x=1;int* p=const_cast(&x);  //ok
3.
int x=1;
const int* p=const_cast(&x);    //ok
4.
int x=1;
const int* p=&x;                                           //ok
5.
volatile int x;
int* p=&x;                                                    //Error: 'initializing' : cannot convert from 'volatile int *' to 'int *'
6.
volatile int x;
int* p=const_cast(&x);                     //ok
7.
int x;
volatile int* p=const_cast(&x);  //ok
8.
int x;
volatile int* p=&x;                                           //ok
最好不要将const_cast用来处理普通类型,而是将const_cast 用来处理类对象,例如下面两个例子:
1.
class A{
public:
A(int x):a(x){}
int a;
};
int main(){
const A x(1);
A &y=const_cast(x);
y.a=2;
cout< return 0;
}
输出:2
2.
const int x=1;
int& p=const_cast(x);
p=2;
cout< cout< 输出:
0023FAE4  0023FAE4
1  2
解释:在第二个例子中p与x的地址相同,值却不同,这是由于编译器优化,把所有的const在编译期记录下来,所以x=1其实是编译期记录的值。


reinterpret_cast:
该操作符用于将一种类型转换为另一种不同的类型,比如可以把一个整型转换为一个指针,或把一个指针转换 为一个整型,因此使用该操作符的危险性较高,一般不应使用该操作符。
例如:
class A{
/* class members*/
};
A a;
int x=reinterpret_cast(a);

dynamic_cast
该转换符用于将一个指向派生类的基类指针或引用转换为派生类的指针或引用,注意 dynamic_cast转换符只能用于含有虚函数的类,其表达式为dynamic_cast<类型>(表达式),其中的类型是指把表达式要 转换成的目标类型,比如含有虚函数的基类B和从基类B派生出的派生类D,

B *pb; D *pd, md; 
pb=&md;
pd=dynamic(pb); 
最后一条语句表示把指向派生类D的基类指针pb转换为派生类D的指针,然后将这个指针赋给派生类D的指针pd,有人可能会觉得这样做没有意义,既然指针 pd要指向派生类为什么不pd=&md;这样做更直接呢?有些时候我们需要强制转换,比如如果指向派生类的基类指针B想访问派生类D中的除虚函数 之外的成员时就需要把该指针转换为指向派生类D的指针,以达到访问派生类D中特有的成员的目的,比如派生类D中含有特有的成员函数g(),这时可以这样来 访问该成员dynamic_cast(pb)->g();因为dynamic_cast转换后的结果是一个指向派生类的指针, 所以可以这样访问派生类中特有的成员。但是该语句不影响原来的指针的类型,即基类指针pb仍然是指向基类B的。如果单独使用该指针仍然不能访问派生类中特 有的成员。一般情况下不推见这样使用dynamic_cast转换符,因为dynamic_cast的转换并不会总是成功的,具体情况在后面介绍。 
dynamic_cast的注意事项:
dynamic_cast转换符只能用于指针或者引用。
dynamic_cast转换符只能用于含有虚函数 的类。
dynamic_cast转换操作符在执行类型转换时首先将检查能否成功转换,如果能成功转换则转换之,如果转换失败,如果是指针则反回一个0值, 如果是转换的是引用,则抛出一个bad_cast异常,所以在使用dynamic_cast转换之间应使用if语句对其转换成功与否进行测试,比如 pd=dynamic_cast(pb);
if(pd){…}else{…},
或者这样测试
if(dynamic_cast(pb)){…}else{…}。 

示例如下:
class A{
public:
virtual void func1(){
cout<<"A::func1"< }
void func2(){
cout<<"A::func2"< }
};
class B:public A{
public:
void func1(){
cout<<"B::func1"< }
void func2(){
cout<<"B::func2"< }
void func3(){
cout<<"B::func3"< }
};
int _tmain(int argc, _TCHAR* argv[])
{
A* p=new B();
p->func1();
p->func2();
dynamic_cast(p)->func1();
dynamic_cast(p)->func2();
dynamic_cast(p)->func3();
return 0;
}
B::func1
A::func2
B::func1
B::func2
B::func3







阅读(528) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~