第八章 C++函数的高级特性
对比C语言的函数,C++增加了重载、内联、const和virtual四种新机制。其中重载和内联机制既可用于全局函数也可用于类的成员函数,const与virtual机制仅用于类的成员函数。
8、1函数重载的概念
函数名相同,作用域相同,参数不同的几个函数可构成重载。C/C++程序可忽略函数的返回值,所以不可根据返回值类型来区分重载函数。全局函数和成员函数因作用域不同,不能构成重载。
当心隐式类型转换导致重载函数产生二义性。如:
void output( int x); //函数声明
void output( float x); //函数声明
因数字本身没有类型,把数字当做参数时将自动进行类型转换。output(0.5)将产生编译错误,因编译器不知将0.5转换成int还是float类型。
8、2成员函数的重载、覆盖与隐藏
8.2.1覆盖:父子类之间,父类函数必须有virtual关键字,函数名字和参数相同。
8.2.2隐藏规则:指派生类的函数屏蔽了与其同名的基类函数。隐藏:父子类之间,函数名相同,无virtual或参数不同时就构成隐藏。展开来说,即:
1)若派生类的函数与基类的函数同名,但参数不同。此时,无论有无virtual关键字,基类的函数都将被隐藏。
2)若派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。
覆盖和隐藏有啥区别呢:覆盖是实现多态的基础,覆盖时,可根据指针实际所指的对象来确定调用的是基类函数还是派生类函数。而隐藏是根据指针类型来确定调用的是基类函数还是派生类函数。
如何摆脱隐藏:
class Base { public: void f(int x); }; |
class Derived : public Base { public: void f(char *str); }; |
将Derived改为:
class Derived : public Base
{
public:
void f(char *str);
void f(int x) { Base::f(x); }
};
8、3参数的缺省值
【规则8-3-1】参数缺省值只能出现在函数的声明中,而不能出现在定义体中。
【规则8-3-2】若函数有多个参数,参数只能从后向前挨个儿缺省。
不合理的使用参数缺省值将导致重载函数产生二义性。
8、4运算符重载
关键字operator加上运算符来表示函数,叫做运算符重载。如:Complex operator +(const Complex &a, const Complex &b);运算符与普通函数在调用时的区别:普通函数,参数出现在圆括号之内;而对于运算符,参数出现在其左右侧。有些运算符是不允许被重载的,用时再看。
8、5函数内联
关键字inline必须与函数定义体放在一起才能使函数称为内联。定义在类声明之中的成员函数将自动称为内联函数。
慎用内联:内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。若执行函数体内的代码时间长,相比于函数调用的开销大,则效率的收获会很少。另一方面,每处内联函数的调用都要复制代码,将消耗更多的内存。不要随便将构造函数和析构函数的定义体放在类声明中。