const函数重载

来源:互联网 发布:霍先生的安之知91妈妈 编辑:程序博客网 时间:2024/05/22 08:19
Const 参数重载解析: 

关于const 重载几乎在所有c++的书中者提到过但大部分只是一句话,例如在《C++ primer》一书中这样描述:“可基于函数的引用形参是指向 const 对象还是指向非 const 对象,实现函数重载。将引用形参定义为 const 来重载函数是合法的,因为编译器可以根据实参是否为 const 确定调用哪一个函数。”
但是这一段描述并没有给出引用、指针和值传递前加const的实质区别是什么。在用非const的指针,引用和值均可转化为const的。这一点没有太多可说明的东东。

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

[cpp] view plain copy
 print?
  1. C++ 代码  
  2. #include<iostream>  
  3.   
  4.  class A{  
  5.  public:  
  6.     A();  
  7.     int foo(int *test);  
  8.     int foo(const int *test);  
  9. };  
  10. A::A(){  
  11. }  
  12.  int A::foo(int *test){  
  13.     std::cout << *test << " A::foo(int *test)" <<std::endl;  
  14.     return 1;  
  15. }  
  16.  int A::foo(const int *test){  
  17.     std::cout << *test << " A::foo(const int *test)" <<std::endl;  
  18.     return 1;  
  19. }  
  20.  int main()  
  21. {  
  22.     const int b =5;  
  23.     int c = 3;  
  24.     A a;  
  25.     a.foo(&b);  
  26.     a.foo(&c);  
  27.     return 1;  
  28. }  
输出:

[cpp] view plain copy
 print?
  1. A::foo(const int *test)  
  2. A::foo(int *test)  

对于a.foo(&b);因为变量b有const修饰所以就调用了int foo(const int *test);对于a.foo(&c);调用int foo(int *test);因为这个是精确匹配的。但是如果没有定义int foo(const int *test);则在代码24行会出现编译错误。反过来如果没有定义函数:int foo(int *test);如下:

[cpp] view plain copy
 print?
  1. 代码  
  2. #include<iostream>  
  3.   
  4.  class A{  
  5.  public:  
  6.     A();  
  7.  //    int foo(int *test);  
  8.      int foo(const int *test);  
  9. };  
  10. A::A(){  
  11. }  
  12.  /*int A::foo(int *test){ 
  13.     std::cout << *test << " A::foo(int *test)" <<std::endl; 
  14.     return 1; 
  15. } 
  16. */  
  17. int A::foo(const int *test){  
  18.     std::cout << *test << " A::foo(const int *test)" <<std::endl;  
  19.     return 1;  
  20. }  
  21. int main()  
  22. {  
  23.     const int b =5;  
  24.     int c = 3;  
  25.     A a;  
  26.     a.foo(&b);  
  27.     a.foo(&c);  
  28.     return 1;  
  29. }  

则输出结果为:

[cpp] view plain copy
 print?
  1. 5 A::foo(const int *test)  
  2. 3 A::foo(const int *test)  

原因c++ primer上讲的很清楚:“We can use a nonconst object to initializer either a const or nonconst reference. However, initializing a constreference to a nonconst object requires a conversion, whereas initializing a nonconst parameter is an exact match.”

 

 

const 成员函数重载的解析:

 

const 成员函数重载的解析和const参数重载解析的原理可以说是一样的。之所以这样说是因为const成员函数的解析可被看做是对函数this参数用const来修饰的过程。例如下面代码:

[cpp] view plain copy
 print?
  1. 代码  
  2. #include<iostream>  
  3.   
  4. class A{  
  5. public:  
  6.     A();  
  7.     int foo(int *test); //可看做:int foo(A *this,int *test);  
  8.     int foo(int *test) const;//可看做:int foo(const A *this,int *test);  
  9. };  
  10. A::A(){  
  11. }  
  12. int A::foo(int *test){  
  13.     std::cout << *test << "foo" <<std::endl;  
  14.     return 1;  
  15. }  
  16. int A::foo(int *test) const {  
  17.     std::cout << *test << "foo const" <<std::endl;  
  18.     return 1;  
  19. }  
  20. int main()  
  21. {  
  22.     int b = 5;  
  23.     const A a;  
  24.     a.foo(&b);  
  25.     return 1;  
  26. }  

上面可以看到编译阶段的调用也是通过对重载函数的别名来实现的。

总结:

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

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

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

补充一点:

这两个版本不属于函数重载。

void fun(int num);//Avoid fun(const int num);//B
在 C 语言里,版本 A 和版本 B 是没有区别的。如果这两个版本定义在相同的作用域中,C 编译器就会认为是函数重定义,而不是函数重载,因为 C 中根本就没有重载的概念。由于 C 中函数参数只有传值一种传递方式,因此 const 只是告诉编译器,形参在函数里面值是不可以被改变的。但是这已经跟实参没有任何关系了,传递进来的只不过是一个副本。与之不同的是 C++ 有引用,传引用会对实参造成影响。



0 0
原创粉丝点击