六一的部落格


关关难过关关过,前路漫漫亦灿灿。



多个函数拥有相同的函数名

多个重载函数必须在形参数量或形参类型上有所区别


不满足重载的情况

  1. 仅返回类型不同
    1Record lookup(Account&);
    2bool lookup(Account&);
  2. 值传递 + 顶层const
    1Record lookup(Phone);
    2Record lookup(const Phone);
    3
    4Record lookup(Phone*);
    5Record lookup(Phone* const);    // 顶层const
    

满足重载的情况

  1. 引用传递 + 底层const
    1Record lookup(Account&);
    2Record lookup(const Account&);
  2. 值传递 + 底层const
    1Record lookup(Phone*);
    2Record lookup(const Phone*); 
    

当传递一个非常量对象引用或者指向非常量对象的指针时,编译器会优先选择非常量的版本


const_cast和重载

之前提到, const_cast用来移除或增加底层const属性, 且要求关联对象不具有顶层const

const_cast的使用场景多在函数重载中

比如进行字符串长度比较时, 通常是不需要拥有对字符串的写权限

1const string &shorterString(const string &s1, const string &s2)
2{
3    return s1.size() <= s2.size() ? s1 : s2;
4}

而当我们需要返回较短字符串时, 后续可能需要对较短字符串做处理. 此时则需要一个非常量版本, 返回较短字符串时, 恢复写权限

1string &shorterString(string &s1, string &s2)
2{
3    auto &r = shorterString(const_cast<const string &>(s1),
4        const_cast<const string &>(s2));
5
6    return const_cast<string &>(r);
7}

函数匹配

function matching

又称作重载确定 overload resolution

可能的结果有3种

  1. 编译器也许能找到一个与实参最佳匹配的函数 best match
  2. 如果找不到任何一个函数与调用的实参匹配, 编译器报错无匹配 no match
  3. 有多于一个函数可以匹配, 但均不是最佳选择, 如同时支持的隐式类型转换; 编译器报错二义性调用 ambiguous call

    调用重载函数时应尽量避免强制类型转换,如果在实际应用中确实需要强制类型转换,则说明设计的形参集合不合理

重载与作用域

 1string read();        // 函数
 2
 3void print(const string &);
 4void print(double);
 5
 6void fooBar(int ival)
 7{
 8    bool read = false;        // 变量,隐藏外层同名变量或函数(隐藏外层作用域中的同名实体)
 9    string s = read();        // 报错
10
11    void print(int);            // 隐藏所有外层print函数
12    print("Value");            // 报错
13    print(ival);                // 调用void print(int)
14    print(3.14);                // 调用void print(int)
15}
16
17// C++中,名字查找发生在类型检查之前

函数重载


多个函数拥有相同的函数名

多个重载函数必须在形参数量或形参类型上有所区别


不满足重载的情况

  1. 仅返回类型不同
    1Record lookup(Account&);
    2bool lookup(Account&);
  2. 值传递 + 顶层const
    1Record lookup(Phone);
    2Record lookup(const Phone);
    3
    4Record lookup(Phone*);
    5Record lookup(Phone* const);    // 顶层const
    

满足重载的情况

  1. 引用传递 + 底层const
    1Record lookup(Account&);
    2Record lookup(const Account&);
  2. 值传递 + 底层const
    1Record lookup(Phone*);
    2Record lookup(const Phone*); 
    

当传递一个非常量对象引用或者指向非常量对象的指针时,编译器会优先选择非常量的版本


const_cast和重载

之前提到, const_cast用来移除或增加底层const属性, 且要求关联对象不具有顶层const

const_cast的使用场景多在函数重载中

比如进行字符串长度比较时, 通常是不需要拥有对字符串的写权限

1const string &shorterString(const string &s1, const string &s2)
2{
3    return s1.size() <= s2.size() ? s1 : s2;
4}

而当我们需要返回较短字符串时, 后续可能需要对较短字符串做处理. 此时则需要一个非常量版本, 返回较短字符串时, 恢复写权限

1string &shorterString(string &s1, string &s2)
2{
3    auto &r = shorterString(const_cast<const string &>(s1),
4        const_cast<const string &>(s2));
5
6    return const_cast<string &>(r);
7}

函数匹配

function matching

又称作重载确定 overload resolution

可能的结果有3种

  1. 编译器也许能找到一个与实参最佳匹配的函数 best match
  2. 如果找不到任何一个函数与调用的实参匹配, 编译器报错无匹配 no match
  3. 有多于一个函数可以匹配, 但均不是最佳选择, 如同时支持的隐式类型转换; 编译器报错二义性调用 ambiguous call

    调用重载函数时应尽量避免强制类型转换,如果在实际应用中确实需要强制类型转换,则说明设计的形参集合不合理

重载与作用域

 1string read();        // 函数
 2
 3void print(const string &);
 4void print(double);
 5
 6void fooBar(int ival)
 7{
 8    bool read = false;        // 变量,隐藏外层同名变量或函数(隐藏外层作用域中的同名实体)
 9    string s = read();        // 报错
10
11    void print(int);            // 隐藏所有外层print函数
12    print("Value");            // 报错
13    print(ival);                // 调用void print(int)
14    print(3.14);                // 调用void print(int)
15}
16
17// C++中,名字查找发生在类型检查之前