Возможна перегрузка Can с двумя версиями функции, постоянной функцией-членом и функцией без const

Я просто столкнулся с различными методами перегрузки, такими как тип переданного параметра, различное количество параметров, тип возвращаемого значения и т. Д. Я просто хочу знать, могу ли я перегрузить функцию следующими двумя версиями


//function which can modify member
String& MyClass::doSomething();

//constant member function
String& MyClass::doSomething() const;

Пожалуйста, дайте мне знать причину этого.


person GG.    schedule 16.06.2010    source источник
comment
На каком языке ты говоришь? Вы должны пометить вопрос языком, если хотите, чтобы он привлек к себе должное внимание.   -  person Oded    schedule 16.06.2010
comment
отредактировано, язык, который я использую, - c ++   -  person GG.    schedule 16.06.2010
comment
Вы не можете перегружать возвращаемый тип в C ++.   -  person mtvec    schedule 17.06.2010


Ответы (5)


Да, ты можешь.

Если у вас есть

MyClass m;
m.doSomething();

Будет вызвана неконстантная версия. Когда у тебя есть

const MyClass m;
m.doSomething();

Будет вызываться константная версия.

person mtvec    schedule 16.06.2010

Самый простой способ понять это - представить объект, для которого вы вызываете метод, как 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

Да, ты можешь это сделать. (@Job, это не перегрузка по типу возвращаемого значения, это перегрузка по «константному состоянию» вызываемого экземпляра класса)

Если экземпляр const, будет вызван второй вариант, если нет, будет вызван первый. Практическое использование заключается в том, что если метод вызывается в экземпляре const, вы, вероятно, также захотите вернуть «const String &» (например, если вы вернете ссылку на член класса), например:

//function which can modify member
String& MyClass::doSomething();

//constant member function
const String& MyClass::doSomething() const;
person Patrick    schedule 16.06.2010
comment
Я знаю, что вопрос не в перегрузке возвращаемого типа, но он упомянул в своем вопросе, что, по его мнению, это возможно. - person mtvec; 17.06.2010

Так используется итератор. У вас есть константный итератор, а также неконстантный.

person Jumix    schedule 16.06.2010

Это не только возможно, но и как часто используемая идиома.

Например, если вызывается const версия функции, может быть возвращена ссылка на версию результата, доступную только для чтения. Но если вызывается версия, отличная от const, создается и возвращается копия, которую получатель может изменить. Реализуя const версию, мы избавляемся от выполнения конструкции, когда знаем, что она не понадобится.

person sigfpe    schedule 16.06.2010