C++ const对函数重载的影响

重载,是指允许存在多个同名函数,而这些函数的参数表不同,即函数名相同但函数的签名不同

重载是在编译阶段实现的,编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数

一、const 修饰成员函数时的重载

第一种情况:

#include<iostream>  
using namespace std;  

void fun(const int i)  
{  
    cout << "fun(const int) called ";  
}  
void fun(int i)  
{  
    cout << "fun(int ) called " ;  
} 

int main()  
{  
    const int i = 10;  
    fun(i);  
    return 0;  
}   

结果:编译错误,提示重定义

第二种情况:

#include<iostream>  
using namespace std;  
   
void fun(char *a)  
{  
  cout << "non-const fun() " << a;  
}  
   
void fun(const char *a)  
{  
  cout << "const fun() " << a;  
}  
   
int main()  
{  
  const char *ptr = "hello world";  
  fun(ptr);  
  return 0;  
}

结果:通过编译,且输出结果为:const fun() hello world

char *a和char * const a,这两个都是指向字符串变量,不同的是char *a是指针变量 而char *const a是指针常量,这就和int i和const int i的关系一样了,所以也会提示重定义。

char *a 中a指向的是一个字符串变量,而const char *a指向的是一个字符串常量,所以当参数为字符串常量时,调用第二个函数,而当函数是字符串变量时,调用第一个函数。

第三种情况:

#include<iostream>  
using namespace std;  
   
void fun(char *a)  
{  
  cout << "non-const fun() " << a;  
}  
   
void fun(char * const a)  
{  
  cout << "const fun() " << a;  
}  
   
int main()  
{  
  char ptr[] = "hello world";  
  fun(ptr);  
  return 0;  
}

结果:编译不通过,提示重定义

总结:对于函数值传递的情况,因为参数传递是通过复制实参创建一个临时变量传递进函数的,函数内只能改变临时变量,但无法改变实参,则这个时候无论加不加const对实参不会产生任何影响。
但是在引用或指针传递函数调用中,因为传进去的是一个引用或指针,这样函数内部可以改变引用或指针所指向的变量,这时const 才是实实在在地保护了实参所指向的变量。
因为在编译阶段编译器对调用函数的选择是根据实参进行的,所以,只有引用传递和指针传递可以用是否加const来重载。

二、const 修饰引用时的重载

#include<iostream>  
using namespace std;  
   
void fun(const int &i)  
{  
    cout << "fun(const int &) called  "<<endl;  
}  
void fun(int &i)  
{  
    cout << "fun(int &) called "<<endl ;  
}  
int main()  
{  
    const int i = 10;  
    fun(i);  
    return 0;  
}

输出结果:fun(const int &) called

int &i 和const int & i 也是可以重载的,原因是第一个i引用的是一个变量,而第二个i引用的是一个常量,两者是不一样的

三、常函数

#include<iostream>  
using namespace std;  
   
class Test  
{  
protected:  
    int x;  
public:  
    Test (int i):x(i) { }  
    void fun() const  
    {  
        cout << "fun() const called " << endl;  
    }  
    void fun()  
    {  
        cout << "fun() called " << endl;  
    }  
};  
   
int main()  
{  
    Test t1 (10);  
    const Test t2 (20);  
    t1.fun();  
    t2.fun();  
    return 0;  
}

输出结果:fun() called

                  fun() const called

常成员函数不能更新类的成员变量,也不能调用该类中没有用const修饰的成员函数,只能调用常成员函数。

非常量对象也可以调用常成员函数,但是如果有重载的非常成员函数则会调用非常成员函数。

四、总结

1.const重载主要是通过能否对传入的参数进行修改为判断的。

2.const参数重载和const函数重载机制都是一样的,因为对于const 函数重载可看做是对隐含的指针this的参数重载。

3.重载是在编译阶段已经完成,对于汇编和链接来说透明的。

4.const 对象只能调用const 方法,非const 对象既能调用const 方法也能调用非const方法,优先调用非const方法。

5.如果重载的函数都是引用或指针,const 变量 只能调用带有const 参数的方法,非const 变量既能调用带const 参数的方法,也能调用不带cosnt 参数的方法,优先调用不带const 参数的方法

  • 11
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值