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?
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.
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.
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.
const is part of the signature, and leaving it off changes the signature, and thus hides the method rather than overrides it. "
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.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With