C++函数彻底兼容C函数定义的风格,可是也作出了一些改进。一方面,C++函数容许使用缺省参数值和占位参数;另外一方面,C++提供了重要的函数重载机制;另外,为了解决C中臭名昭著的宏缺陷问题,C++提供了内联函数的机制(C99以后也支持这个特性)。从C++11开始,函数定义支持后置返回类型。数组
C++中能够在函数声明时为参数提供一个默认值,当函数调用时若是不提供实参,就使用这个默认值:函数
int func(int x = 0); int main(int argc, char *argv[]) { printf("func() = %d\n", func()); return 0; } int func(int x) { return x; }
注意:默认值只在函数声明时有效,虽然函数定义中也能够写默认值,可是会被函数声明中的默认值覆盖。优化
函数默认参数的规则是:指针
在C++中能够为函数提供占位参数。占位参数只有参数类型声明,可是没有参数名;这样,在函数的实现中是没法使用这个参数的:code
int func(int) { return 0; } int main(int argc, char *argv[]) { func(1); // 虽然参数无心义,可是仍是要提供来经过编译。 return 0; }
占位参数存在的意义是:兼容C语言中可能出现的不规范的写法,也能够配合默认值来一块儿使用。作用域
若是同一个做用域内的几个函数名称相同,可是参数列表不一样,那它们就是重载函数:编译器
void print(const char *cp); void print(const int *begin, const int *end); void print(const int ia[], size_t size);
函数重载有如下几个注意点:编译
注意:返回值类型不一样不能做为重载的条件。class
若是函数以值传递参数,那么const
不能构成重载:扩展
void func(int arg); void func(const int arg); // 错误:对func的重定义
可是,若是以指针或者引用来传递参数,那么const就能够构成重载了:
void func1(int *arg); void func1(const int *arg); // 正确:声明了新函数 void func1(const int *const arg); // 正确:声明了新函数 void func2(int &arg); void func2(const int &arg); // 正确:声明了新函数
另外一方面,const成员函数
和非const成员函数
一样能够构成函数重载:
class object { public: int func(); const int func() const; // 正确:声明了新函数 };
编译器会如下面的顺序肯定要调用的函数:
顶层const
或者从实参中移除顶层const
const
转换实现的类型匹配。因为编译器须要根据重载规则去挑选与函数指针参数列表一致的函数,而且要严格地匹配函数类型与函数指针的类型,所以没法直接经过函数名获得重载函数的入口地址:
void func(int); void func(double); int main(int argc, char *argv[]) { void * v = func // 错误:没法经过函数名获得函数的地址。 void(*pFunc1)(int) = func; // 正确:得到了void func(int)的入口地址。 void(*pFunc2)(double) = func; // 正确:得到了void func(double)的入口地址。 return 0; }
为了兼容旧有的C语言代码库,必须以C语言的编译规则来编译函数,所以须要使用以下的方式:
__cplusplus
宏来检查是否使用了C++extern "C"
来让编译器以C语言方式编译函数#ifdef __cplusplus extern "C" { #endif void func(); // 这个函数将以C语言的方式编译。 #ifdef __cplusplus } #endif
C++中推荐之内联函数来代替宏代码片断。C++一样以直接替换代码块的方式来处理内联函数,同时没有著名的宏缺陷问题。可使用inline
关键字来请求编译器将函数之内联函数的方式处理 (编译器可能忽略这个请求):
inline void func() {...}
注意:
内联函数声明时inline
必须和函数定义结合在一块儿,不然编译器会忽略该请求。
inline
,也可能会被内联编译。__forceinline
__attribute__((always_inline))
内联函数存在一些限制:
C++11提供了函数的后置返回类型,用于兼容自动类型推断:
auto func() -> void {} // 等价于 void func() {}