一、static_cast
- 功能:用来强迫隐式类型转换,或称为显式的类型转换
- 例如:
- 将非const对象转换为const对象(但是不能将底层const对象转换为非const对象,这个只有const_cast才能做到)
- 将int转换为double,反之亦然
- 也可以将void*指针转换为其他类型指针,将pointer-to-base转换为pointer-to-derived
- 注意事项:
- 使用static_cast会去除编译器的警告,但是我们必须自己清楚转换有效,否则转换无效可能会产生未定义的结果
演示案例
- 我们将一个整型对象转换为double类型
int i = 10, j = 1; double slope1 = i / j; //一般的强制类型转换,编译器可能会报出警告 double slope2 = static_cast<double>(j) / j; //显式地强制类型转换,编译器无警告
- 当我们把较大的算术类型赋值给较小的类型时,一般的强制类型转换编译器会发出警告
- 但是当我们使用static_cast后,编译器就不会报出警告
演示案例
- static_cast对于编译器无法自动执行的类型转换也非常有用
- 例如我们可以使用static_cast找回存在于void*指针中的值:
double num = 3.14; void *p = # //任何非常量对象的地址都能存入void* double *dp = static_cast<double*>(p); //将void*转换回初始的指针类型
二、reinterpret_cast
- 功能:通常为运算对象的位模式提供较低层次上的重新解释
- 例如将一个pointer-to-int转换诶一个int
- 使用reinterpret_cast是非常危险的,我们必须自己编写正确的代码
- reinterpret_cast本质上依赖于机器。要向安全地使用reinterpret_cast必须对设计的类型和编译器实现转换的过程都非常了解
演示案例
- 例如有下面的转换
int *ip; char *pc = reinterpret_cast<char*>(ip);
- 我们必须牢记pc所指的真是对象是一个int而不是字符
- 如果把pc当成普通的字符指针使用那么就会产生未定义的后果。例如:
int *ip; char *pc = reinterpret_cast<char*>(ip); //编译器虽然不报错,但是后果未定义 string str(pc);
三、const_cast
- 功能:用来将对象的常量性移除
- 注意事项:
- 只能改变运算对象的底层const
- const_cast只能改变表达式的常量属性,而不能改变表达式的数据类型
- const_cast常用于有函数重载的上下文
演示案例
- 将底层const对象转换为非const对象
const char *pc; //正确,但是通过p写值是未定义的行为 char *p = const_cast<char*>(pc);
- 当我们去掉某个对象的const性质之后,编译器就不再阻止我们对该对象进行写操作了,因此写操作会产生未定义的后果
演示案例
- const_cast只能改变表达式的常量属性,而不能改变表达式的数据类型
const char* cp; //错误,static_cast不能去除const性质 char*q = static_cast<char*>(cp); //正确,字符串常量值可以转换为string类型 static_cast<string>(cp); //错误,const只能去除const性质,但是不能进行数据类型的转换 const_cast<string>(cp);
class
1.class的get/set方法:提供相对安全方式访问成员变量;
2.class的构造函数- 作用:初始化对象的属性
- 特点:a.没有函数返回值; b.函数名与类型相同; c.可以重载 d.实例一个对象会自动调用构造函数
class A { public: A() { cout << "A" << endl; } }
构造函数种类:默认的无参构造函数、无参构造函数、类型转换构造函数、默认拷贝构造函数、拷贝构造函数、移动拷贝构造函数(c++11)。
- 1.自定义的拷贝函数:
A(const A &other) { m_num = other.m_num; cout << "A cope A" << endl; }
- 2.类型转换构造函数:explicit防止发生隐式类型转换
explicit A(int num) { cout << "A int" << endl; m_num = num; }
- 3.类型转换运算符重载:支持static_cast()
operator int() { return m_num; } operator string() { return m_name; } A& operator =(const A &other) { cout << "A operator A" << endl; m_num = other.m_num; }
小结:
- 默认的无参构造函数:类里灭有任何自己定义的构造函数时,会默认生成;
- 类型转换构造函数:一个参数的构造函数;存在风险:将其他类型默认转换为类类型;通过explicit修饰构造函数,防止发生默认转换
- 默认的拷贝构造函数:当类中无拷贝构造函数时,系统会默认生成一个拷贝构造函数:A (const A &a);
- 自定义拷贝构造函数:赋值运算符重载
- 拷贝构造函数:
A a1(a); A a3 = a
- 赋值运算符
a2 = a;