1. 隐式转换(implicit)
-
数值类型
a.低字节类型向高字节类型转换(正常转换)
short a = 20;
int b = a;
b.高字节向低字节类型转换(可能会导致数据丢失并且编译器报警告)
double a = 10.2;
float b = a;
gcc -Wconversion -o test test.cxx
warning: conversion to 'int' alters 'double' constant value.
- 指针转换
a.
Null pointer 能够被转换成任何类型的pointer;
b
.任何类型的pointer都能被转换成void pointer;
c.
pointer能够向上转换成base class pointer;
- 类(class)
a. Single-argument constructor:使用某对象去初始化另一对象;
b. Assignment operator: 对象赋值;
c. Type-cast operator: 借助于operator关键字进行转换。
// implicit conversion of classes:
#include <iostream>
using namespace std;
class A {};
class B {
public:
// conversion from A (constructor):
B (const A& x) {}
// conversion from A (assignment):
B& operator= (const A& x) {return *this;}
// conversion to A (type-cast operator)
operator A() {return A();}
};
int main ()
{
A foo;
B bar = foo; // calls constructor
bar = foo; // calls assignment
foo = bar; // calls type-cast operator
return 0;
}
d. explicit 关键字可禁止构造函数参数进行隐式转换
#include <iostream>
using namespace std;
class A {};
class B {
public:
explicit B (const A& x) {}
B& operator= (const A& x) {return *this;}
operator A() {return A();}
};
void fn (B x) {}
int main ()
{
A foo;
B bar (foo);
bar = foo;
foo = bar;
// fn (foo); // not allowed for explicit ctor.
fn (bar);
return 0;
}
2.显示转换(Explicit)
- 强制类型转换(type-casting)
double x = 10.3;
int y;
y = int (x); // functional notation
y = (int) x; // c-like cast notation
没有限制的强制类型转换可能会造成运行时错误或者其他一些意想不到的错误。
#include <iostream>
using namespace std;
class Dummy {
double i,j;
};
class Addition {
int x,y;
public:
Addition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};
int main () {
Dummy d;
Addition * padd;
padd = (Addition*) &d;
cout << padd->result();
return 0;
}
- dynamic_cast<new_type>(expression)
dynamic_cast只能用于类指针和类引用之间的转换,它进行类型安全的检测以确保转换结果的正确性。
a. 向上转换(将子类指针转换成父类指针)
b. 向下转换(将父类指针转换成子类指针),条件只有父类指针指向的是子类对象的时候转换才能成功;
c. 它还可以用来null pointer和一般指针的转换。
#include <iostream>
#include <exception>
using namespace std;
class Base { virtual void dummy() {} };
class Derived: public Base { int a; };
int main () {
try {
Base * pba = new Derived;
Base * pbb = new Base;
Derived * pd;
pd = dynamic_cast<Derived*>(pba);
if (pd==0) cout << "Null pointer on first type-cast.\n";
pd = dynamic_cast<Derived*>(pbb);
if (pd==0) cout << "Null pointer on second type-cast.\n";
} catch (exception& e) {cout << "Exception: " << e.what();}
return 0;
}
第一个转换从pba转到pd是可以的,而第二个转换则返回的是null.
(dynamic_cast 用于指针时,转换失败返回null,用于引用时,转换失败抛出异常。)
- static_cast<new type>(expression)
class A { /* ... */ };
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a);
b.可以进行数值转换
float fv = 10.1;
int iv = 21;
cout << static_cast<int>(fv) <<endl;
cout << static_cast<double>(iv) <<endl;
c. 不能进行不相关指针类型的转换
int iv = 10;
double* pd = static_cast<double*>(&iv);//error, can not convert from int* to double *
class a {/* */};
class b {/* */};
b* pb = new b;
a* pa = static_cast<a*>(pb); //error
- reinterpret_cast<new type>(expression)
class A { /* ... */ };
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a);
b. 可将整形和指针之间进行相互转化(二进制的拷贝),一个很好地用途就是hash
unsigned int Hash( void *p ) {
unsigned int val = reinterpret_cast<unsigned int>( p );
return (unsigned int)( val ^ (val >> 31));
}
- const_cast<new type>(expression)
const char * c = "sample text";
char * pc = const_cast<char *> (c) ;
cout<<pc<<endl;
pc[1] = '2'; //error, try to modify the string constant.