zoukankan      html  css  js  c++  java
  • [C++] 函数重载

    函数重载

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

    void print(const char *cp);
    void print(const int *beg, const int *end);
    void print(const int ia[], size_t size);
    
    int j[2] = {0,1};
    print("Hello World!");
    print(j, end(j) - begin(j));
    print(begin(j), end(j));

    main函数不能重载

    对于重载函数来说,它们应该在形参数量或形参类型上有所不同。

    不允许两个函数除了返回类型外其他所有的要素都相同。

    有时候两个形参列表看起来不一样,实际上是相同的

    int calc(const int &a);
    int calc(const int&);

    形参名只是起到了帮助记忆的作用。有没有它并不影响形参列表的内容

    重载和const形参

    顶层const不影响传入函数的对象。一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开

    Record lookup(Phone);
    Record lookup(const Phone);
    // const Phone为顶层const、
    Record lookup(Phone*);
    Record lookup(Phone* const);
    // Phone* const为顶层const

    以上函数存在重复声明

    如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载,此时const是底层的

    Record lookup(Account&);
    // 函数作用域Account的引用
    Record lookup(const Account&);
    // 函数作用于常量引用
    Record lookup(Account*);
    // 作用于指向Account指针
    Record lookup(const Account*);
    // 作用于指向常量的指针

    我们只能把const对象传递给const形参

    相反的,非常量可以转换成const

    所以以上4个函数都能作用于非常量对象或者指向非常量对象的指针。

    当我们传递一个非常量对象或者指向非常量对象的指针使,编译器会优先选用非常量版本的函数

    const_cast和重载

    比较两个string对象的长度,并返回较短的那个引用

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

    我们可以对两个非常量的string实参调用这个函数,但返回的结果是const string的引用。

    所以我们需要一个新的函数,当实参不是常量时,得到的结果是一个普通的引用。可以使用const_cast完成。

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

    首先将实参强制转换成对const的引用,然后调用shorterString的const版本,const版本返回对const string的引用,然后将其转换成一个普通的string&。

    重载与作用域

    一般来说,将函数声明置于局部作用域内不是一个明智的选择。

    重载对作用域的一般性质并没有改变,如果我们在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体。在不同作用域中无法重载函数名

    在作用域中调用函数时,编译器首先寻找对该函数名的声明,一旦在该作用域内找到所需名字,编译器会自动忽略外层作用域中的同名实体。剩下来就是检查函数调用是否有效了。

    在C++中,名字查找在类型检查之前

    string read();
    void print(const string &);
    void print(double);
    void fooBar(int ival)
    {
        bool read = false;
        // 新作用域,隐藏了外层read函数
        string s = read();
        // 错误,read是bool类型变量
        void print(int);
        // 在作用域内声明函数
        print("Value: ");
        // 错误,作用域内只有print(int),外层print被隐藏
        print(ival);
        // 正确,调用当前print(int)
        print(3.14);
        // 正确,调用当前print(int).
    }
    void print(const string &);
    void print(double);
    void print(int);
    void fooBar2(int ival) 
    {
        print("Value: ");
        // 重载调用
        print(ival);
        // 重载调用
        print(3.14);
        // 重载调用,void print(double)
    }
    void print(const string &);
    void print(double);
    void print(int);
    void fooBar2(int ival) 
    {
        print("Value: ");
        // 重载调用
        print(ival);
        // 重载调用
        print(3.14);
        // 重载调用,void print(double)
    }
  • 相关阅读:
    Oracle EBS OM 主要API示例
    WIP 投料报 Invalid Serial Number
    物料事务处理interface与temp解析
    INV_TXN_MANAGER_PUB.PROCESS_TRANSACTIONS
    FND Debug Log(FND_LOG_MESSAGES)
    Oracle Apps DBA 常用命令
    详解EBS接口开发之WIP模块接口
    使用Java管理千台规模Linux服务器_入门
    windows下spark开发环境配置
    零成本实现Android/iOS自动化测试:基于Appium和Test Perfect
  • 原文地址:https://www.cnblogs.com/immjc/p/8093620.html
Copyright © 2011-2022 走看看