zoukankan      html  css  js  c++  java
  • C++函数的高级特性-函数重载

     对比于C 语言的函数,C++增加了重载(overloaded)、内联(inline)、const 和virtual
    四种新机制。其中重载和内联机制既可用于全局函数也可用于类的成员函数,const 与
    virtual 机制仅用于类的成员函数。

    1.重载(overloaded)

    重载的理由:

    1:在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,即函数重载。
    这样便于记忆,提高了函数的易用性

    2:类的构造函数需要重载机制。因为C++规定构造函数与类同名构,造函数只能有一个名字。如果想用几种不同的方法创建对象该怎么办?别无选择,只能用重载机制来实现。所以类可以有多个同名的构造函数。

    重载的实现:

    它们是如何区分的呢?我们自然想到函数接口的两个要素:参数与返回值
    如果同名函数的参数不同(包括类型、顺序不同),那么容易区别出它们是不同的函数。

    如果同名函数仅仅是返回值类型不同,有时可以区分,有时却不能。例如:
    void Function(void);
    int Function (void);
    上述两个函数,第一个没有返回值,第二个的返回值是int 类型。如果这样调用函数:
    int x = Function ();
    则可以判断出Function 是第二个函数。

    void Eat(Beef ...);
    void Eat(Fish ...);
    void Eat(Chicken ...);

    问题是在C++/C 程序中,我们可以忽略函数的返回值。在这种情况下,编译器和程序员都不知道哪个Function 函数被调用。所以只能靠参数而不能靠返回值类型的不同来区分重载函数。编译器根据参数为每个重载函数产生不同的内部标识符。例如编译器为上述示例中的三个Eat 函数产生象_eat_beef、_eat_fish、_eat_chicken 之类的内部标识符(不同的编译器可能产生不同风格的内部标识符)。

    如果C++程序要调用已经被编译后的C 函数,该怎么办?
    假设某个C 函数的声明如下:
    void foo(int x, int y);
    该 函数被C 编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字用来支持函数重载和类型安全连接。由于编译后的名字不 同,C++程序不能直接调用C 函数。C++提供了一个C 连接交换指定符号extern“C”来解决这个问题。
    例如:
    extern “C”
    {
    void foo(int x, int y);
    ⋯ // 其它函数
    }
    或者写成
    extern “C”
    {
    #include “myheader.h”
    ⋯ // 其它C 头文件
    }
    这就告诉C++编译译器,函数foo 是个C 连接,应该到库中找名字_foo 而不是找_foo_int_int。C++编译器开发商已经对C 标准库的头文件作了extern“C”处理,所以我们可以用#include 直接引用这些头文件。

    注意:不是两个函数的名字相同就能构成重载。全局函数和类的成员函数同名不算重载,因为函数的作用域不同。例如:
    void Print(...); // 全局函数
    class A
    {...
    void Print(...); // 成员函数
    }
    不论两个Print 函数的参数是否不同,如果类的某个成员函数要调用全局函数Print,为了与成员函数Print 区别,全局函数被调用时应加‘::’标志。如
    ::Print(...); // 表示Print 是全局函数而非成员函数

    注意:当心隐式类型转换导致重载函数产生二义性
    第一个output 函数的参数是int 类型,第二个output 函数的参数是float 类型。由于数字本身没有类型,将数字当作参数时将自动进行类型转换(称为隐式类型转换)。语句output(0.5)将产生编译错误,因为编译器不知道该 将0.5 转换成int 还是float 类型的参数。隐式类型转换在很多地方可以简化程序的书写,但是也可能留下隐患。

    # include <iostream.h>
    void output( int x); // 函数声明
    void output( float x); // 函数声明
    void output( int x)
    {
    cout << " output int " << x << endl ;
    }
    void output( float x)
    {
    cout << " output float " << x << endl ;
    }
    void main(void)
    {
    int x = 1;
    float y = 1.0;
    output(x); // output int 1
    output(y); // output float 1
    output(1); // output int 1
    // output(0.5); // error! ambiguous call, 因为自动类型转换
    output(int(0.5)); // output int 0
    output(float(0.5)); // output float 0.5
    }
    隐式类型转换导致重载函数产生二义性

    转自:http://blog.csdn.net/sendy888/article/details/1738997

  • 相关阅读:
    PythonのTkinter基本原理
    使用 Word (VBA) 分割长图到多页
    如何使用 Shebang Line (Python 虚拟环境)
    将常用的 VBScript 脚本放到任务栏 (Pin VBScript to Taskbar)
    关于 VBScript 中的 CreateObject
    Windows Scripting Host (WSH) 是什么?
    Component Object Model (COM) 是什么?
    IOS 打开中文 html 文件,显示乱码的问题
    科技发展时间线(Technology Timeline)
    列置换密码
  • 原文地址:https://www.cnblogs.com/ymy124/p/2451424.html
Copyright © 2011-2022 走看看