内联函数:一般函数进行调用时要将程序执行权转到被调用函数中,然后在返回调用他的函数中;而内敛函数在调用时,是将调用表达式用内联函数体来替换。示例如下:
1.在类内部声明内联函数叫做 隐式内联函数。如:
class display
{
int t;
public:
inline void
}
2.在类外部声明内联函数叫做显示内联函数。如:
inline int max(int a,int b)
{
return a>b?a:b;
}
内联函数于define的区别:
(1)内联函数在运行时可调试,而宏定义不可以; (2)编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数), 而宏定义则不会;(3)内联函数可以访问类的成员变量,宏定义则不能;(4)在类中声明同时定义的成员函数,自动转化为内联函数。
注意:内联函数中不允许使用循环语句,递归函数不能作为内联函数。
内联函数的优点:
调用函数实际上将程序执行顺序转移到函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。 这种转移操作要求在转去前要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保存地址继续执行。因此,函数调用要有一定的时间和空间方面的开销,于是将影响其效率。特别是对于一些函数体代码不是很大,但又频繁地被调用的函数。
虚函数:为了继承,实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。(构造函数不能是虚函数,因为构建对象必须知道具体的类型信息,若构造函数是虚函数,编译器无法获知构建继承树上的哪种类型。)
若存在虚函数,编译器会为它所在的类插入一段数据(vptr指针),并创建一个表(vtbl),vptr指针指向vtbl表,vtbl的作用就是保存类中虚函数的地址,vptr指针存放在各自的实例对象中。
注意:1. 非类的成员函数不能定义为虚函数,类的成员函数中的静态成员函数和构造函数也不能定义为虚函数。析构函数定义为虚函数,当使用delete删除指向派生类的对象指针时,就会调用派生类的析构函数。
2.当基类的成员函数声明为虚函数后,派生类中的同名函数(函数名、参数列表、返回类型相同)自动成为虚函数。
3.如果声明了某个成员函数为虚函数,则在该类中不能出现和这个成员函数同名并且返回值、参数个数、类型都相同的非虚函数。在以该类为基类的派生类中,也不能出现和这个成员函数同名并且返回值、参数个数、类型都相同的非虚函数。
4.C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现。子类可以重写父类的虚函数实现子类的特殊化。
构造函数的执行先执行父类,再执行子类。若父类的析构函数不是虚函数,则只调用父类的析构函数。若父类的析构函数是虚函数,则先调用子类再调用父类。
纯虚函数:纯虚函数就是基类只定义了函数体,没有实现过程,例如:virtual void Eat() = 0;有纯虚函数的类不能直接实例化,需要派生类来实现函数定义;
函数继承:
- 子类拥有父类的所有属性和方法(除了构造函数和析构函数)。
- 子类可以拥有父类没有的属性和方法。
- 子类是一种特殊的父类,可以用子类来代替父类。
- 子类对象可以当做父类对象使用。
类和对象的权限:
模板函数:
函数模板和类模板 函数模板针对参数类型不同的函数; 类模板针对数据成员和成员函数类型不同的类; 利用模板原因是为了写出与类型无关的代码; 模板的声明和定义只能在全局,命名空间或类范围内进行。不能在局部,函数内进行,比如不能在main函数中声明和定义一个模板;
例:
template<class T> T fun(T a, T b)
{
return (a > b) ? a : b;
}
int main()
{
char bb = '1';
char b = '2';
char test = fun(bb, b);
cout << test << endl;
return 0;
}