const函数重载

时间:2013-07-26 07:23:31

标签: c++ overloading const-correctness

我很困惑为什么下面的代码没有产生任何错误,因为传递给display的参数属于同一类型,即charconst真的有区别吗?

#include<iostream>

using namespace std;

void display(char *p)
{
    cout<<p;
}
void display(const char *p)
{
    cout<<p;
}

int main()
{
    display("Hello");
    display("World");
}

修改 根据答案,永远不会调用第一个显示,这是正确的,输出也是如此。

但是假设我这样做:

int main()
{
    char *p="Hello";
    display(p);//now first display is called.
    display("World");
}

编译器给出一个warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]但是它先调用display.Does意味着字符串现在不再被视为常量?

6 个答案:

答案 0 :(得分:11)

const char*char *实际上并不相同。后者允许修改指向char,而第一个则会阻止它。

另请注意,如果这些是类方法void display()void display() const也是有效的重载。后者意味着方法不能改变对象的状态。

考虑以下代码:

void    display(char *s)
{
  std::cout << "Display" << std::endl;
}

void    display(const char *s)
{
  std::cout << "Display with const" << std::endl;
}

int     main()
{
  char  *str = strdup("boap");
  const char *str2 = "toto";
  /* It is a string literral "bound" as a char *.                                                                               
     Compiler will issue warning, but it still compiles.                                                                        
     Avoid to do that, it's just an exemple */
  char  *not_safe = "not_safe";

  display("llama");
  display(str2);
  display(str);
  display(not_safe);
}

这将打印Display with const两次,然后两次Display。见there。 现在,让我们看看为什么:

  • "llama"是一个字符串文字,然后被解析为const char *
  • str2是指向字符串文字的指针。由于其类型为const char*,因此也会转为const重载。
  • not_safe也是指向字符串文字的指针。但是,其类型为char *这不正确。它指向的内存是只读的,尝试修改它会导致崩溃。但是,变量的类型仍为char *,因此解决了非const重载问题。
  • str是一个char *指针,它指向的字符串不是只读的。修改其内容是有效的,因为它的类型为char *,它将解析为非const重载。

答案 1 :(得分:3)

问题是"Hello""World"等字符串文字的类型为const char[6]。这可以衰减到const char*,但不会衰减到char*。所以过载需要const char*

 void display(const char *p);

是更好的匹配。正如@JamesKanze指出的那样,有一个函数可以使char*接受一个字符串文字,但是试图修改指向的数据会导致未定义的行为。因此,将字符串文字传递给此类函数是不安全的。通过适当的警告设置,GCC产生以下内容:

  

警告:已弃用从字符串常量转换为'char *'

在任何情况下,如果出现两次重载,例如你所显示的重载,那么const char*的重载就会胜出。

答案 2 :(得分:0)

传递给这两个函数的参数实际上并不相同。

第一个采用char*:指向char的指针。

第二个采用const char*:指向const char的指针。

所以你看,这里的区别实际上在于指针是否指向一个可以改变的对象。这绝对是您希望能够重载函数的属性。

答案 3 :(得分:0)

您是否可以修改对象绝对是一个有用的信息,具体取决于您可能想要调用不同的行为!考虑一下:

void foo(int * p) { ++(*p); }
void foo(int const * p) { std::cout << *p << '\n'; }

答案 4 :(得分:0)

字符串“Hello”和“World”的大小在编译时是已知的,不能修改。它们是常量的编译时字符数组。

在C和C ++中,一个数组,例如可以使用指针引用char a[6],即a实际上是char *。由于“Hello”和“World”的数组不能在运行时修改,因此它们的类型基本上是const char *

编译器识别出这一点并正确执行display的重载解析,因为只有一个函数(display(const char* p))将const char*作为参数。这就是为什么这两个函数没有歧义,你没有得到你期望得到的错误。

答案 5 :(得分:0)

“因为传递给display的参数是相同的类型,即char。”

这里没有参数是“const char *”。数据类型是但是const限定符表示你硬编码的文字字符串不是可以改变的东西。

“const真的有区别吗?”

是的const限定符有所作为。 在Display(char *)中,您可以更新传递的null-terminate字符串的内容,但不能更新Display(const char *)。这一事实允许编译器进行更多优化。

但请阅读http://www.possibility.com/Cpp/const.html这是开始有效使用const的好资源。