Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const Function Overloading [duplicate]

I am confused why the following code is not producing any error ,because the arguments passed to display are of same type i.e char.Does const really makes difference?

#include<iostream>

using namespace std;

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

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

EDIT As per answers,the first display is never called,which is correct and so is the output.

But suppose I do it like :

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

Compiler gives a warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] but then it calls first display.Does it mean that string is now no more taken as constant?

like image 540
Naveen Avatar asked Jul 26 '13 07:07

Naveen


People also ask

Can const functions be overloaded?

Overloading on the basis of const type can be useful when a function return reference or pointer. We can make one function const, that returns a const reference or const pointer, other non-const function, that returns non-const reference or pointer.

Can we overload const functions in C++?

C++ allows member methods to be overloaded on the basis of const type. Overloading on the basis of const type can be useful when a function returns a reference or pointer.

What is const in operator overloading?

A const reference is simply that a reference that is const. It does not change the const-ness of the actual object you are passing in. An example of non-const operator overloading: Here is an example of operator overloading where the parameter is not const.

Can const method be overridden?

const is part of the signature, and leaving it off changes the signature, and thus hides the method rather than overrides it. "


2 Answers

const char* and char * are actually not the same. The later allow for modifying the pointed char, while the first one will prevent that.

Also note that if those were class methods, void display() and void display() const would also be valid overloads. The later would imply that the method must not change the object's state.

Consider this code:

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);
}

This will print Display with const twice, and then twice Display. See there. Now, let's see why:

  • "llama" is a string literal, and then is resolved as a const char *.
  • str2 is a pointer to a string literal. Since its type is const char*, this also revolves to the const overload.
  • not_safe is also a pointer to a string literal. However, its type is char *: this is not correct. The memory it points to is read-only, and trying to modifies it will result in a crash. However, the type of the variable is still char *, so this resolve to the non-const overload.
  • str is a char * pointer, and the string it points to is not read-only. Modifying its content is valid, and since its type is char *, it will resolve to the non-const overload.
like image 51
Xaqq Avatar answered Oct 19 '22 01:10

Xaqq


The issue is that string literals such as "Hello" and "World" have type const char[6]. This can decay to const char*, but not to char*. So the overload taking const char*,

 void display(const char *p);

is the better match. As @JamesKanze points out, it would be possible for a function taking char* to accept a string literal, but attempting to modify the data pointed at would result in undefined behaviour. For this reason, it is unsafe to pass string literals to such functions. With suitable warning settings, GCC produces the following:

warning: deprecated conversion from string constant to ‘char*’

In any case, in the presence of two overloads like the ones you have shown, the one taking const char* wins.

like image 3
juanchopanza Avatar answered Oct 19 '22 02:10

juanchopanza