类的构造顺序:
先构造基类的构造函数,再构造类中得成员变量,再构造该类的构造函数。
拷贝构造的形参传引用,不然会造成栈溢出。(生成形参会递归调用拷贝构造,无限循环!)
运算符重载经常重载的是(== > <)
函数声明使用默认形参
注意点:
- 默认的形参必须是从右往左的顺序,并且要求指定默认值的形参必须是连续的。
即如 int func(int a = 0, int b, int c, int d =0);这种写法是非法的!
- 带有默认形参的函数声明包含多种情况的函数,因此 不能再定义被其包含的重载函数,即如下:
函数的哑元参数
- 哑元参数:所谓哑元参数就是函数定义时,只有类型,而没有名称的形参,即如:int add(int a, int b, int c, int)
- 哑元参数的意义:
- 实际开发时,某个函数由于系统的升级而需要改变,但是要求兼容之前的老版本,则可以将不再使用的参数改为哑元参数。
- 有时候,由于函数重载的需要,需要使用哑元参数来区分两个重载函数。
内联函数
- 内联函数和宏的区别:
- 宏是由预处理对宏进行替代;内联函数是通过编译器控制来实现的。
- 内联函数是真正的函数,只是在要用到的时候会想宏一样展开,从而减少函数的参数入栈/出栈操作,减少了调用的开销;
- 内联函数的定义,只需要在函数定义时在前面加上【inline】关键字即可,注意仅仅在声明上加【inline】关键字是没有用的!
- 内联函数从本质上是通过占用空间来换取时间的,即将内联函数的代码先加载到内存中,占据了一些内存空间,这样做的好处是在调用内联函数时执行效率非常快,节省了调用普通函数保存现场、跳转、恢复现场的操作。但这同时就要求内联函数的函数体必须短小精炼,如果相关函数冗杂繁复,不但会占用很大的内存空间,而且在函数复杂的情况下,相对的调用函数时的出入栈及跳转、保护现场的时间可忽略不计,即此时内联函数并没有节省时间,特别如循环、递归的函数,并不适合写成内联函数。
函数指针
- 函数指针的本质是 指针
- 声明的标准格式为: 数据类型 (*函数名)(参数列表)
- 函数指针赋值的条件:
- 函数指针和它指向函数的参数个数和类型必须相同
- 函数指针的类型和函数的返回值类型必须相同
- 函数数组指针的示例:
回调函数
- 回调函数就是:通过函数指针调用函数的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,这个函数便被称为回调函数。
引用
- 引用和指针的区别
- 指针在定义时,可以不初始化,而引用在定义时必须初始化;
即 char* a;(正确) char& b;(错误)
- 指针变量指向的地址可以根据需要动态修改,而引用只要和某个变量绑定后就不能再被修改;
- 指针的本身需要占用4个字节来存放地址,而引用本身不用分配内存空间;
- 使用sizeof求指针变量的大小总是确定的4个字节,表示地址所占的空间是4个字节的,而用sizeof求引用的大小是不确定的,它的大小是由所引用的源头变量决定的!
C++中的四种数据类型强制转换
- 静态类型转换运算符(static_cast)
- 标准形式为: static_cast<T>(val); 其中 T为将要转换成的数据类型,val表示将要进行类型转换的变量名。
- Static_cast用于所用系统类型之间的转换,但不能用于系统内置类型指针的转换。(系统类型就是基本数据类型,如short/long/int/char/float等等)
- 指针类型转换运算符(reinterpret_cast)
- 标准形式为: reinterpret_cast<T*>(val);
- reinterpret_cast运算符可以用于任意类型指针之间的转换,也可以用于进行没有任何关联类型之间的转换。
- const类型转换运算符(const_cast)
- const_cast类型转换能够剥离一个对象的const属性,也就是说允许对常量进行修改,具体使用场合:
- 常量指针被转换成非常量指针,仍然可以改变原来常量的值
- const_cast类型转换能够剥离一个对象的const属性,也就是说允许对常量进行修改,具体使用场合:
- 常量引用被转化成非常量引用,仍然可以改变原来常量的值
通过结果我们能够看到,相同的地址,他们的值却是不同的!这是因为在C++中如果有一个变量被定义成const,那么我们读取该变量的值默认都是不变的,即便通过某些间接方式修改了其内存值,通过该变量读取的值还是初始设定的值。为了解决这个保护机制,我们可以在const常量前加关键字volatile,如下:
- 常量的地址被转换成非常量地址,仍然可以改变原来常量的值
即在const前加volatile关键字。
- 动态类型转换运算符(dynamic_cast)
- 动态类型转换适用于具有多态性的父子类的指针或者引用之间的转换。