1.引用
数据类型 & 引用名 = 初始值(变量名)
2.const
.1常量
const 类型 变量名
const int var = 10;
.2常量引用
const 类型& 引用名
int var; const int & ref_var = var; //不能对ref_var进行修改
.3常量对象
类名 const 对象名
#include<iostream> #include<string> using namespace std; const string str_obj = "qwq";//定义时初始化 以后不能修改
.4常量成员函数
类名::函数名(形参表)const
class MyClass { public: MyClass() {}; ~MyClass() {}; int get_x(void)const;//只负责返回类x的值 并不修改成员的值 所以加const private: int x; }; int MyClass::get_x(void)const { return x; }
如果对成员写操作 编译时会报错,提高安全系;
.5常量数组
类型 const 数组名[大小]
int const arr[10] = {1,2,3,4,5,6,7,8,9,10};
.6常量指针
const 类型* 指针名
int const arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int const *p_int = arr;//指向数组arr //*p_int =10; //不能修改指针指向的值
.7指针常量
类型* const 指针名
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int *const p_int = arr; *p_int = 10;//正确 p_int = arr;//错误 指向原来的也不对 不可修改
指针常量是指针本身是一个常量,指向地址不能修改(指向的单语言不一定是常量)
常量指针是不能修改指向内存地址的值
const int* p = &value; int * const q = &value;
这两个语句的含义是不同的,前者是"所指内容不可变",后者则是"指向的地址不可变"
3.函数的默认参数
int def_var_1 = 20; void default_parameter_func(int num1 = def_var_1, int num2 = 3, char ch = ‘*‘);
4.内联函数
inline
inline int max(int a, int b) { return a > b ? a : b; }
5.函数重载
void display(); void display(const char*); void display(int one ,int two); void display(float number);
6.强制类型转换
C语言
int b; float a = (float)b;
C++
int b; float a = float(b);//这种方式类似函数
+4
static_cast
static_cast<new_type>(expr)
主要有以下用法:(1)用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。(2)用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。(3)把空指针转换成目标类型的空指针。(4)把任何类型的表达式转换成void类型。 注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
#include<iostream> #include <string> using namespace std; class Base {}; class Derived:public Base{}; int main() { float f = 12.3; float* pf = &f; int n = static_cast<int>(f); //ok n=12 //int* pn = static_cast<int*>(pf);//无法从float*转换为int* void* pv = static_cast<void*>(pf);//ok int* pn2 = static_cast<int*>(pv);//ok 但pn2无意义 Base * p_a = new Base; Derived * p_b = static_cast<Derived*>(p_a); Base o_a; Derived o_b; o_a = *p_b;//正确 隐式转换 子对象转换为父对象 o_a = static_cast<Derived>(*p_b);//正确 显示转换 o_b = *p_a;//错误 不存在父对象转换为子对象 o_b= static_cast<Derived>(*p_a);//错误 return 0; }
dynamic_cast
dynamic_cast <new_type> (expr)
把expr转换为newtype对象
将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理
即会作一定的判断。
对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;
对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。
注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。例如在下面的代码中将CBasic类中的test函数不定义成
virtual时,编译器会报错:error C2683: dynamic_cast : “CBasic”不是多态类型
#include <iostream> using namespace std; class CBasic { public: virtual int test(){return 0;} // 一定要是 virtual }; class CDerived : public CBasic { public: virtual int test(){ return 1;} }; int main() { CBasic cBasic; CDerived cDerived; CBasic * pB1 = new CBasic; CBasic * pB2 = new CDerived; //dynamic cast failed, so pD1 is null. CDerived * pD1 = dynamic_cast<CDerived * > (pB1); //dynamic cast succeeded, so pD2 points to CDerived object CDerived * pD2 = dynamic_cast<CDerived * > (pB2); //dynamci cast failed, so throw an exception. // CDerived & rD1 = dynamic_cast<CDerived &> (*pB1); //dynamic cast succeeded, so rD2 references to CDerived object. CDerived & rD2 = dynamic_cast<CDerived &> (*pB2); return 0; }
const_cast
const_cast <new_type> (expression)
const_cast转换符是用来移除变量的const或volatile限定符
const int constant = 21; const int* const_p = &constant; int* modifier = const_cast<int*>(const_p); *modifier = 7;
reinterpret_cast
reinterpret_cast <new_type> (expression)
处理无关类型之间的转换.可以把一个指针转换为一个整数,也可以把一个整数转换为一个指针,还可以不同指针之间的转换
- 从指针类型到一个足够大的整数类型
- 从整数类型或者枚举类型到指针类型
- 从一个指向函数的指针到另一个不同类型的指向函数的指针
- 从一个指向对象的指针到另一个不同类型的指向对象的指针
- 从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针
- 从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针
这也是一个很不安全的转换,只有转换为原始类型,彩色正确使用reinterpret_cast的方式
#include <iostream> // Returns a hash code based on an address unsigned short Hash( void *p ) { unsigned int val = reinterpret_cast<unsigned int>( p ); return ( unsigned short )( val ^ (val >> 16)); } using namespace std; int main() { int a[20]; for ( int i = 0; i < 20; i++ ) cout << Hash( a + i ) << endl; } //如果跟我一样是64位的系统,可能需要将unsigned int改成 unsigned long才能运行。
7.输入输出流
ostream
istream
cout.put(71).put(79).put(79).put(68).put(‘\n‘); //GOOD
cout.put(65+32)//字符a