隐式类型转换
显式类型转换
xxx_cast <类型> (表达式)
用于非多态类型之间的转换,不提供运行时的检查来确保转换的安全性。
主要有如下:
(1)基本数据类型转换
(2)int转换成enum
(3)基类和子类之间指针和引用的转换
上行转换:把子类的指针或引用转换成父类,这种转换是安全的(通常使用默认转换)。
下行转换:把父类的指针或引用转换成子类,这种转换是不安全的,也需要程序员来保证(通常使用dynamic_cast)。
int n = 97;
cout << n << '\t' << (char)n << '\t' << static_cast<char>(n) << endl;
int n = 1;
cout << n/2 << '\t' << (float)n/2 << '\t' << static_cast<float>(n)/2 << endl;
enum Week{
SUN,MON,TUE,WED,THU,FRI,SAT
};
Week day = 0;
编译上述代码出现如下错误:
g++编译错误:error: invalid conversion from ‘int’ to ‘Week’
clang++编译错误:error: cannot initialize a variable of type 'const Week' with an rvalue of type 'int'
把代码Week day = 0;改为Week day = static_cast(0);可以消除上面的错误。
已知存在继承关系的两个类Base和Derive
class Base{
public:
void Print(){
cout << "Base" << endl;}
};
class Derive:public Base{
public:
void Print(){
cout << "Derive" << endl;}
};
// 对象
Derive d;
Base b = static_cast<Base>(d);
b.Print();
// 引用
Base& fb = static_cast<Base&>(d);
fb.Print();
// 指针
Base* pb = static_cast<Base*>(new Derive);
pb->Print();
通常使用隐式转换
// 对象
Derive d;
Base b = d;
b.Print();
// 引用
Base& fb = d;
fb.Print();
// 指针
Base* pb = new Derive;
pb->Print();
这种转换不安全,通常使用dynamic_cast。
void指针转换成目标类型的指针,这种转换是不安全的,也需要程序员来保证;
如下代码编译出错,因为不能把void*转换成其他具体指针。
void* pd = new Derive;
Base* pb = pd; // error: invalid conversion from ‘void*’ to ‘Base*’
pb->Print();
把Base pb = pd;改为Base pb = static_cast
常量赋值给非常量时,会出现下面编译错误。
const int a = 10;
// 指针
const int* cp = &a;
int* p = cp;// error: invalid conversion from ‘const int*’ to ‘int*’
// 引用
const int& cf = a;
int& f = cf;// error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers
const_cast主要作用是移除类型的const属性。
(1)常量指针被转化成非常量指针,并且仍然指向原来的对象
(2)常量引用被转换成非常量的引用,并且仍然指向原来的对象
(3)const_cast一般用于修改底指针,如const char* p形式
const int a = 10;
// 指针
const int* cp = &a;
int* p = const_cast<int*>(cp);
// 引用
const int& cf = a;
int& f = const_cast<int&>(cf);
(1)const_cast<>在<>中通常只用指针或者引用类型。
(2)基本类型常量,因为存在常量展开的情况,const_cast<>并不会改变后面的值。
const int a = 10;
cout << "a:" << a << endl;
const_cast<int&>(a) = 11; // 已经改变a所在内存的值
cout << "a:" << a << endl; // 常量展开,看不到改变
cout << "*(&a)" << *(&a) << endl; // 直接访问内存可以看到改变
int *p = &a;
cout << "*p:" << *p << endl; // 直接访问内存可以看到改变
(1)通常在const成员函数中是不能修改成员变量。
(2)在const函数中this指针是const类型,所以所有成员不能被直接改变。
例如:
提供一个打印出Set/Get次数的功能
#include
using namespace std;
class Integer{
int n;
int setter;
int getter;
public:
Intege