I just came across various overloading methods like type of parameter passed, varying number of parameters, return type etc. I just want to know that can I overload a function with following two version
//function which can modify member String& MyClass::doSomething(); //constant member function String& MyClass::doSomething() const;
Please let me know the reason behind it.
Yes you can.
If you have
MyClass m;
m.doSomething();
The non-const version will be called. When you have
const MyClass m;
m.doSomething();
The const version will be called.
The easy way to understand this, is to think of the object you are calling the method on as the 0th parameter:
e.g.: Think of
String& MyClass::doSomething();
MyClass mc;
mc.doSomething();
as a fancy, compiler supported way of doing this:
String& MyClass_doSomething(MyClass *this);
MyClass mc;
MyClass_doSomething(&mc);
Now, overloading based on constness is just a special case of overloading by parameter types:
String& MyClass::doSomething();
String& MyClass::doSomething() const;
can by thought of as something like this:
String& MyClass_doSomething(MyClass *this);
String& MyClass_doSomething(const MyClass *this);
As to the usefullness of this, the easiest examples are the begin
and end
methods on various std::
containers. If the vector
/string
/whatever is non const, and you call begin()
, you'll get back an iterator
that can be used to modify the contents of the original container. Clearly, this shouldn't be allowed for containers marked const
, so, thanks to the const/non const overloading, calling begin()
on a const vector return a const_iterator
that can be used to read the contents of the vector, but not modify it.
e.g.
string nc = "Hello world";
for (string::iterator iString = nc.begin(); iString != nc.end(); ++iString)
{
cout << *iString;; // legal to read
*iString = toupper(*iString); // legal to write
}
const string c = "Hello world again";
for (string::const_iterator iString = c.begin(); iString != c.end(); ++iString)
{
cout << *iString;; // legal to read
// *iString = toupper(*iString); // Writing is illegal
}
As to overloading by return type, you can't do it in C++. However, you can simulate it fairly decently.
Yes, you can do this. (@Job, this is not overload on return type, this is overload on 'const-state' of the called class instance)
If the instance is const, the second variant will be called, if it isn't, the first one is called. The practical use is that if the method is called on a const instance, you probably also want to return a "const String&" (e.g. if you return a reference to a member of the class), like this:
//function which can modify member
String& MyClass::doSomething();
//constant member function
const String& MyClass::doSomething() const;
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