玩命加载中 . . .

6.4-函数重载


6.4 函数重载

如果同一作用域内的几个函数名字相同但形参列表不同,称之为重载(overload)函数

tips

  • 不允许两个函数除了返回类型外其他所有的要素都相同。
  • 一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来。
Record lookup(Phone);
Record lookup(const Phone);  // 一样的
  • 如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载,此时的const是底层的
Record lookup(Account&);
Record lookup(const Account&);  // 新函数,作用于常量引用

注意:当传递一个非常量对象或者非常量对象的指针时,编译器会优先选用非常量版本的函数

const_cast和重载

const string& shorterString(const string& s1, const string& s2) {
    return s1.size() < s2.size() ? s1 : s2;
}

这里返回常量引用,当传入非常量对象时,需要一个非常量的版本,返回非常量引用

string& shorterString(string& s1, string& s2) {
    auto& r = shorterString(const_cast<const string&> s1, const_cast<const string&> s2);
    return const_cast<string&> (r);
}

先把非常量引用转为常量引用,调用常量引用版本的函数,再把返回的常量结果转为非常量

6.5 特殊用途语言特性

6.5.1 默认实参

注意:一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值

在给定的作用域中一个形参只能被赋予一次默认实参,不能重复声明

string screen(int, int, char = ' ');
string screen(int, int, char = '*');    // 错误:重复声明

局部变量不能作为默认实参,只要表达式的类型能转换为形参所需要的类型,该表达式就能作为默认实参

int ht();
int wd = 80;
char def = ' ';     // 全局变量
string screen(int = ht(), int = wd, char = def);

string window = screen();   // 调用screen(ht(), 80, ' ');

如果是在函数作用域里面

void fun2() {
    def = '*';  // 修改了全局变量def
    int wd = 100;   // 局部变量不影响全局变量
    window = screen();  // 调用screen(ht(), 80, '*');
}

6.5.2 内联函数和constexpr函数

内联函数可避免函数调用的开销,将函数指定为内联函数(inline),通常就是将它在每个调用点上“内联地”展开

inline const string &horterString(const string &s1, const string &s2)
{
    return s1.size() <= s2.size() ? s1 : s2;
}

在函数声明和定义中都能使用关键字inline,但是建议只在函数定义时使用

一般来说,内联机制适用于优化规模较小、流程直接、调用频繁的函数。内联函数中不允许有循环语句和switch语句,否则函数会被编译为普通函数

constexpr函数是指能用于常量表达式的函数。constexpr函数的返回类型及所有形参的类型都得是字面值类型。另外C++11标准要求constexpr函数体中必须有且只有一条return语句,但是此限制在C++14标准中被删除

constexpr int new_sz()
{
    return 42;
}

constexpr int foo = new_sz();   // ok: foo是常量表达式

constexpr函数被隐式地指定为内联函数


文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录