2010-10-20 3 views
1

В этом проблема. Я написал эту функцию, чтобы вернуть ссылку на элемент i вектора-члена, чтобы этот элемент можно было отредактировать. Вот код:Как написать конструктор const, который возвращает ссылку на объект-член, поэтому он может быть отредактирован?

Letter& Literal::get (int i) const { 

    return lit_m.at (i); //Vector of Letter objects 
} 

Но г ++ не позволит мне назначить этот элемент неконстантного ссылки:

g++ -o literal.o -c literal.cpp 
literal.cpp: In member function ‘Letter& Literal::get(int) const’: 
literal.cpp:34: error: invalid initialization of reference of type ‘Letter&’ from expression of type ‘const Letter’ 

Как это могло быть решена? Моя идея состоит в том, чтобы создать такую ​​функцию, как функция at() векторов, поэтому она будет const, поскольку она не редактирует сам объект, но она должна позволить мне редактировать возвращаемый объект ... Возможно ли это?

SOLVED: Мне просто нужно было перегрузить функцию :), поэтому объявите const и неконстантную версию. Я боялся, что const и non-const перегрузка не была разрешена, но я увидел, что это const изменяет список аргументов, что делает возможным.

ответ

5

Проблема эта функция член:

Letter& get (int i) const 

вы объявили его Const, и из-за того, функция

const T& at() const 

член вектора класса называется, возвращая вам константную ссылку на i-й элемент, поэтому вы не можете его изменить.

Если вам действительно нужно изменить этот элемент, не объявляйте функцию get() как const и возвращайте ссылку на элемент, как вы сейчас делаете.

Кстати, вы объявили функцию const, и вы возвращаете неконстантную ссылку.

0

Это не const-correct. Вы меняете переменную-член класса (вектор), поэтому g ++ видит это как ошибку. Когда вы объявляете метод как const и возвращаете переменную-член, ожидается, что возвращаемое значение используется для inspection, а не mutation.

2

Существует очень веская причина, по которой возникает ошибка. Объект вашего класса должен быть постоянным, чтобы сохранить его состояние. Когда вы возвращаете ссылку на одну из своих внутренних переменных, вы позволяете кому-то изменять значение этой внутренней переменной, тем самым изменяя состояние объекта, делая его более не постоянной функцией.

Возможно, что если класс Literal содержит вектор указателей на объекты Letter вместо буквенных объектов, вы можете успешно вернуть ponter в один из этих объектов Letter без проблем.

Letter* Literal::get (int i) const { 
    return lit_m.at (i); //Vector of pointers to Letter objects 
} 

Возможно статья все дело с указателями должны читать (или любой другой язык, позволяющий константным ключевым словом, но в 10 раз больше, если указатели участвуют) можно найти here. Честно говоря, я, вероятно, должен снова рассмотреть это снова.

+0

Фактически вы дали ему решение. Пока указатель никогда не будет NULL, вы можете разыменовать его. – CashCow

+0

Я не был уверен, действительно ли это было, потому что я думал, что это был метод const, он, вероятно, фактически вернул бы либо «Letter * const», либо «const Letter *», а во втором случае он был бы в том же как и раньше. – Anthony

Смежные вопросы