C++总结之函数重载

1)函数名称相同

2)函数声明在同一个作用域内(一个类构成一个作用域,因此子类不能重载继承自父类的函数,多继承时,继承自不同父类的函数也不能构成重载)

example:

class Person
{
public:
    void love(){}
};

class Man:public Person
{
private:
    void love(int i){}
};

class Car
{
public:
    void on()
    {

    }
};

class Computer
{
public:
    void on(int arg)
    {

    }
};

class ModernCar:public Car,public Computer
{

};

void love()
{
    Man m;
    m.love();   ///错误,函数名称的查找期间并不区分访问限制
    ///继承自父类的同名函数不能构成重载,已被隐藏尽管子类的love(int)是private的,而父类的love是public的

    ModernCar mc;
    mc.on();   ///错误,来自不同空间的函数不能重载,导致歧义
}

3)using声明的引入对函数的重载有影响,其中using namespace相当于把某个命名空间内的名称复制到当前作用域,而using namespace::name 则相当于告知编译器在namespace中查找name。具体影响看例子:

example:

namespace XXX
{
    void fx()
    {
        cout<<"xxx"<<endl;
    }
}

void fx(int a)
{
    cout<<"::"<<endl;
}

void fca()
{
    ///ok
    using namespace XXX;
    fx(0);
    fx();
}

void fcb()
{
    using XXX::fx;
    fx();  ///ok;
    fx(0); 错误,
}

4)函数形参的个数或者类型不同,普通类型的形参不区分const,指针或者引用类型的形参其指涉物的const型别不同也可以构成重载。对于成员函数而言是否为const函数,是针对右值还是左值的函数也可以构成重载。函数的返回值类型不能构成重载

///这两个函数不构成重载,有歧义
int love(int i)
{

}

void love(const int i)
{

}

///这四个函数构成重载
void love(int *p)
{

}

void love(const int *p)
{

}

void love(int &arg)
{

}

void love(const int &arg)
{

}

class Boy
{
public:
    ///这两个函数构成重载
    void love()const
    {

    }

    void love()
    {

    }
};

class Girl
{
public:
    ///这两个函数构成重载
    void love()&
    {

    }

    void love()&&
    {

    }
};

5)函数调用发生时,先从最里层的作用域查找函数名,如果未找到,再到外层查找,直到全局空间,如果任未找到相同的函数名,则查找失败。一旦在某一层找到了相同的函数名,马上停止向外层空间的查找,该层空间所找到的所有相同函数名构成候选函数(对于类作用域来说,父类是子类的外层作用域;对于多继承来说,一个子类会出现多个外层空间,此时,每个外层空间都平等对待,即不存在找到名字后马上停止的情况,而是要查找完它所有的父类,该过程完成后,如果出现不同父类拥有同名函数,则调用出错)第一个例子已经可以说明这个问题了

6)函数名查找成功,则判断可以调用的函数组,实以调用的函数其形参个数和实参必须相同,实参必须可以转化到形参,如果没有可以调用的函数,则调用出错。

7)可调用函数组确定下来以后,根据实参到形参所需做的转化类型判断最佳调用。如果没有最佳调用,则调用出错。

8)形参到实参的转化排序:

①精确匹配,即形参和实参个数类型完全一致

实参到形参的转化是数组名或函数名到其对应指针的转化

针对对象本身的const转化(对于引用来说不存在常引用,因此不存在这种类型的转化,对于指针来说是指指针本身常量属性的转化)

②实参到形参需要常量转化,只有唯一一种情况:给指涉到常量对象类型的指针或引用形参传递一个普通的实参对象

③实参到形参的转化通过数值提升

④实参到形参的转化需要算术或指针转化

⑤类类型的转化

9)除此之外,小于int的整数类型会被自动提升至int类型。在一次实参到形参的转化中,类类型的转化只能发生一次。

void love(short s)
{
    cout<<"I love short"<<endl;
}

void love(int i)
{
    cout<<"I love int"<<endl;
}

class Button
{
public:
    Button()=default;
    Button(const string &s):name(s){}
    Button(string &&s):name(move(s)){}
private:
    string name;
};

void love()
{
    love('c');  ///output:I love int  <pre name="code" class="cpp">   ///小于int的转化会被自动提升至int

Button bx("Ok"); ///由"OK"转化至string属于一次类类型转化,然后紧接着可以直接调用 ///Button(string &&)构造函数 Button by = "Reset"; ///错误,由"Reset"到string属于一次类类型转化 ///由于采用复制构造,因此需要将string再转化为Button才可以调用其复制
///构造函数,故而需要两次类类型转化,而这是不被允许的 }


10)实参到形参的转化过程中如果有类类型转化参与,只有当两个函数提供相同的类类型转化时才考虑数值转化,否则调用出现歧义,主要是在写类的类型转化函数式需要注意,一般算术类型和类类型的转化只需提供一个转化函数,其余的转化可以自动进行。

class Demon
{
public:
    Demon()=default;
    Demon(int){}
    Demon(double){}

    operator int()const
    {
        return 0;
    }

    operator double()const
    {
        return 0.0;
    }
};

void love(long double d)
{

}

void love()
{
    Demon d;
    love(d);   ///错误,可通过不同的类类型转化得来,
    ///其后的算数转化优先级不再考虑,产生歧义
}

11)类的运算符重载需要考虑的重载函数既有类的成员函数,也有非成员函数

class Woman
{
public:
    bool operator==(const Woman &w)
    {
        return true;
    }
};

class Girl
{
public:
    bool operator==(const Girl &g)const
    {
        return true;
    }
};

bool operator==(const Girl &g,const Woman &w)
{
    cout<<"Woman isn't equal to Girl"<<endl;
    return false;
}

bool operator==(const Woman &w,const Girl &g)
{
    cout<<"Girl isn't equal to Woman"<<endl;
    return false;
}

void gw_equal()
{
    Girl ga,gb;
    Woman wa,wb;
    cout<<(ga == gb)<<endl;   ///output:1
    cout<<(wa == wb)<<endl;   ///output:1

    cout<<(ga == wa)<<endl;
    ///output:
    ///Woman isn't equal to Girl
    ///0
    cout<<(wa == ga)<<endl;
    ///output:
    ///Girl isn't equal to Woman
    ///0
}
时间: 2024-08-03 02:02:44

C++总结之函数重载的相关文章

javascript 函数重载 overloading

函数重载 https://en.wikipedia.org/wiki/Function_overloading In some programming languages, function overloading or method overloading is the ability to create multiple methods of the same name with different implementations. Calls to an overloaded functi

day4 函数重载

函数的重载 1.函数重载的定义:在同一个类中,有一个以上的同名函数,只要函数的参数列表或参数类型不一样即可,与返回值无关, 这些统称为方法的重载. 2.函数的重载存在的原因:为了增强方法的阅读性,优化了程序设计. 案例1:九九乘法表 1 private static void print99() { 2 for(int i = 1 ; i<= 9 ; i ++){ 3 for(int j = 1 ; j<=i ; j++){ 4 System.out.print(i+"*"

c++中的函数重载

c++中的函数重载 什么是函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数.类型或者顺序)必须不同,这组函数被称为重载函数. 函数重载的作用 重载函数常用来实现功能类似而所处理的数据类型不同的问题,能减少函数名的数量,提高程序的可读性. 重载函数的构成说明 定义一个类,添加一系列函数名相同的函数,但参数形式各有不同,测试一下能否构成重载. #include <iostream> using names

C++函数重载实现的原理以及为什么在C++中调用C语言编译的函数时要加上extern &quot;C&quot;声明

C++相对于C语言而言支持函数重载是其极大的一个特点,相信在使用C语言的时候大家如果要写一个实现两个整型数据相加的函数还要写一个浮点型数据相加的函数,那么这两个函数的名字绝对不可以一样,这样无疑在我们使用这个函数的时候增加了复杂性,但是在C++中我们却可以很好的解决这个问题,因为在C++中函数是支持重载的也就是说两个函数的函数名可以一样,这样并不会出现函数名重定义的问题,但是我们在使用的时候也要遵守一些规定,这些规定我们会在接下来的讨论中提到,下面我们就来分析在C++中函数是如何实现函数的重载的

C++ 函数重载与函数匹配

<C++ Primer>笔记,整理关于函数重载与函数匹配的笔记. 函数重载 void func(int a); //原函数 void func(double a); //正确:形参类型不同 void func(int a, int b); // 正确:形参个数不同 int func(int a); //错误:只有返回类型不同 typedef int int32; void func(int32 a); //与原函数等价:形参类型相同 void func(const int a); //与原函数

0607pm克隆&amp;引用类&amp;加载类&amp;面向对象串讲&amp;函数重载

克隆class Ren{ public $name; public $sex; function __construct($n,$s) { $this->name=$n; $this->sex=$s; } function __clone()//改变克隆的对象内容 { $this->name="李思思";//this代表复本对象 $that->name="李思思";//that代表原本的,后来废弃了 }}$r=new Ren("张丹

函数重载、覆盖、多态

#include <iostream> using namespace std; /* *对于纯虚函数可以实现也可以不实现,但派生类一定要覆盖基类的纯虚函数.否则派生类仍然是抽象类 * *如果派生类覆盖基类的虚函数,则基类的指针或引用实际指向子类对象,那么通过该指针或引用调用虚函数时,将调用子类的虚函数;如果不是虚函数,则调用父类的函数. * */ class PEOPLE { public: int age; //派生类必须实现抽象类的纯虚函数,否则派生类仍然是抽象类 virtual voi

为什么C++支持函数重载

对于C++语言作为一种欲与C兼容的语言,C++语言保留了一部分过程式语言和特点,foo_int_int这样的名字包含了函数名.函数参数数量及类型信息,C++语言就是靠这种机制来实现函数重载的. 假设某个函数的原型为: // 模块A头文件 moduleA.h #ifndef MODULE_A_H #define MODULE_A_H int foo( int x, int y ); #endif 该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类

C++文件头,命名空间,new和delete,内联函数,引用,函数重载,构造函数和析构函数,深拷贝和浅拷贝,explict,this指针

 目  录 1       开始学习C++.............................................................................................................. 4 1.1       C++的头文件.................................................................................................

C++的函数重载和main函数之外的工作

今天被问到一个C++的函数重载问题,一下子没反应过来,这种基础的问题竟然忘记了,以下记录一下这些忘记的内容.     函数重载 函数重载的定义是:在相同的作用域中,如果函数具有相同名字而仅仅是形参表不同,此时成为函数重载.注意函数重载不能基于不同的返回值类型进行重载. 注意函数重载中的"形参表"不同,是指本质不同,不要被一些表象迷惑.main函数不能被重载. 下面三组定义本质是相同的,不是重载: 1)int sum (int &a); 和 int sum (int &)