Самый простой способ понять это - представить объект, для которого вы вызываете метод, как 0-й параметр:
например: подумайте о
String& MyClass::doSomething();
MyClass mc;
mc.doSomething();
как причудливый, поддерживаемый компилятором способ сделать это:
String& MyClass_doSomething(MyClass *this);
MyClass mc;
MyClass_doSomething(&mc);
Теперь перегрузка на основе констант - это просто частный случай перегрузки по типам параметров:
String& MyClass::doSomething();
String& MyClass::doSomething() const;
можно представить себе примерно так:
String& MyClass_doSomething(MyClass *this);
String& MyClass_doSomething(const MyClass *this);
Что касается полезности этого, то простейшими примерами являются методы begin и end в различных std:: контейнерах. Если _8 _ / _ 9_ / something не является константой, и вы вызываете begin(), вы получите обратно iterator, который можно использовать для изменения содержимого исходного контейнера. Ясно, что это не должно быть разрешено для контейнеров, помеченных const, поэтому, благодаря перегрузке const / non const, вызов begin() для константного вектора возвращает const_iterator, который можно использовать для чтения содержимого вектора, но не для его изменения.
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
}
Что касается перегрузки по типу возвращаемого значения, то в C ++ этого сделать нельзя. Однако вы можете довольно прилично смоделировать это.
person
Eclipse
schedule
16.06.2010