Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.84/58: Рейтинг темы: голосов - 58, средняя оценка - 4.84
 Аватар для Roof
155 / 155 / 44
Регистрация: 03.11.2010
Сообщений: 393

Константные функции-члены класса, возвращающие ссылку на константу

08.08.2011, 21:09. Показов 13283. Ответов 64
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Упражняюсь по книге Липпмана, выполняю задания по теме классы.
Необходимо реализовать класс person, который способен хранить имя и адрес человека, а также создать функции, возвращающие при обращении имя и адрес.
Вопрос, который ставит автор книги: "Должны ли эти функции быть константными? Объясните почему."
Вот тут я начал путаться. Вот моя реализация:
файл person.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef PERSON_H_
#define PERSON_H_
 
class person {
public:
    //конструктор, принимающий две строки типа string
    person( std::string &_name, std::string &_addres ) :
        name( _name ), addres( _addres ) {
    }
    //метод, возвращающий addres
    const std::string &get_addres() const {
        return addres;
    }
    //метод, возвращающий name
    const std::string &get_name() const {
        return name;
    }
 
private:
    //поле для хранения имени
    std::string name;
    //поле для хранения адреса
    std::string addres;
};
 
#endif /* PERSON_H_ */
Для тестирования класса, файл test_class_person.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "person.h"
using namespace std;
 
int main() {
    string str1 = "Alexander";
    string str2 = "Zelenogradsk";
    person pers( str1, str2 );
    cout << pers.get_name() << " " << pers.get_addres() << endl;
    
    string str3 = pers.get_name();
    str3 += "222";
    cout << str3 << " " << pers.get_name();
    return 0;
}
Я решил так
1) Константными эти функции должны быть, так как они не меняют значений переменных-членов объекта.
2) Возвращать они должны лишь константную ссылку на строку, а не просто тип string, дабы избежать ненужного копирования.
Прав ли я? Если нет, то объясните почему.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.08.2011, 21:09
Ответы с готовыми решениями:

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

Константные функции-члены ?
Для чего использовать #define ? не имеют права изменять поля класса почему ? class Array { ... inline double operator...

класс «Строка» (данные-члены класса – строчка, функции-члены класса – операции)
Помогите пожалйуста с реализацией программы... Реализовать класс «Строка» (данные-члены класса – строчка (указатель на массив, ...

64
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
10.08.2011, 18:07
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от lavan Посмотреть сообщение
Возврат const string & необходим чтобы избежать возможности изменять private часть класса без использования интерфейса
Это неверно, от const_cast никак в таком случае не застраховаться.
0
Заблокирован
10.08.2011, 19:44
const_cast малость не подходит под категорию "случайное изменение инкапсулированных данных", всё по делу
1
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
10.08.2011, 19:48
Цитата Сообщение от LosAngeles Посмотреть сообщение
const_cast малость не подходит под категорию "случайное изменение инкапсулированных данных"
Только вот некоторые бездари используют приведение типа в стиле Си, которому на всё ***.
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
10.08.2011, 21:14
Цитата Сообщение от LosAngeles Посмотреть сообщение
const_cast малость не подходит под категорию "случайное изменение инкапсулированных данных"
Где здесь фраза "случайное изменение инкапсулированных данных":
Цитата Сообщение от lavan Посмотреть сообщение
Возврат const string & необходим чтобы избежать возможности изменять private часть класса без использования интерфейса
?
0
Заблокирован
10.08.2011, 21:30
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Где здесь фраза "случайное изменение инкапсулированных данных":

?
Потому что если вы умышленно меняете то, что не предназначалось для изменения, как вы предложили с помощью const_cast, то вы - вредитель. Автор того сообщения имел в виду, когда можно неумышленно изменить то, что не подлежит изменению в виду неудачного интерфейса. То есть интерфейс должен способствовать правильному использованию данных и препятствовать их неправильному использованию. Это и было сказано в исходном сообщении. На мой взгляд, это совершенно ясно, так что не надо переспрашивать, "где зедсь фраза".
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
11.08.2011, 11:02
Цитата Сообщение от Сыроежка Посмотреть сообщение
На мой взгляд, это совершенно ясно
Это на ваш взгляд. А, например, на мой взгляд "избежать возможности изменять" и "неумышленно изменить" - разные вещи. Так что, как видите, вы не являетесь последней инстанцией и не уполномочены додумывать за людьми недосказанное. Пока автор не уточнил свои слова, не стоит так категорично пояснять то, как вы их поняли.
2
2022 / 1621 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
11.08.2011, 12:09
Пока так и не увидел ни одного реального довода в пользу НЕиспользования константных ссылок в качестве возвращаемого значения. Пример вроде
C++
1
const string& sss = ( person( str1, str2 ).get_name() );
выглядит как-то не очень убедительно. А по поводу const_cast полностью согласен с вышесказанным:
Цитата Сообщение от Сыроежка Посмотреть сообщение
если вы умышленно меняете то, что не предназначалось для изменения, как вы предложили с помощью const_cast, то вы - вредитель.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
11.08.2011, 12:26
Цитата Сообщение от rangerx Посмотреть сообщение
Пока так и не увидел ни одного реального довода в пользу НЕиспользования константных ссылок в качестве возвращаемого значения.
Утверждение вроде "Пользователи класса НЕ должны иметь прямого доступа к его скрытым членам" - не аргумент?

Цитата Сообщение от Deviaphan Посмотреть сообщение
Только вот некоторые бездари используют приведение типа в стиле Си
Если это на мой садовый участок кирпич, так и средствами С++ вполне можно ссылку на константный объект сделать ссылкой на неконстантный... Вообще думаю, первое, что сделает начинающий и не слишком хорошо учившийся программист при сообщении компилятора "... bla bla bla const bla bla bla..." - постарается от константности избавиться. И таки добьётся своего. Что будет дальше - загадка...
1
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
11.08.2011, 13:14
Цитата Сообщение от rangerx Посмотреть сообщение
Пока так и не увидел ни одного реального довода в пользу НЕиспользования константных ссылок в качестве возвращаемого значения.
Основная пробелама ссылок, это то что они могут пережить объект на который ссылаются. Чем не повод (наряду с соблюдением инкапсуляции) не возвращать их?
Цитата Сообщение от Сыроежка Посмотреть сообщение
Потому что если вы умышленно меняете то, что не предназначалось для изменения, как вы предложили с помощью const_cast, то вы - вредитель.
Я никого константность снимать и не призываю, я лишь указал на то, что возврат константной ссылки на внутренности объекта никак не позволит
Цитата Сообщение от lavan Посмотреть сообщение
избежать возможности изменять private часть класса без использования интерфейса
Кроме того, если вы, как разработчик класса, даете лазейку в виде применения const_cast клиентам, то это исключительно Ваша проблема, что Вы не сумели продумать дизайн, действительно исключающий возможность изменения внутреннего состояния объекта Вашего класса за его пределами.
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
11.08.2011, 13:35
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Основная пробелама ссылок, это то что они могут пережить объект на который ссылаются. Чем не повод (наряду с соблюдением инкапсуляции) не возвращать их?
Ага, и от указателей по той же причине отказаться. Да и вообще от C++
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
11.08.2011, 13:37
grizlik78, а кто предлагал отказаться? Предлагается не возвращать ссылки на закрытые члены класса, и всего-то))
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
11.08.2011, 13:48
Лучший ответ Сообщение было отмечено как решение

Решение

Ну меня, по-крайней мере, не убедили.
Если пользователь случайно или намеренно меняет значения по ссылкам/указателям на константу, то он ССЗБ. Надо такому пользователью в одном из вызовов вернуть ссылку на настоящую константу, пусть попрыгает
5
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
11.08.2011, 14:06
Цитата Сообщение от grizlik78 Посмотреть сообщение
Надо такому пользователью в одном из вызовов вернуть ссылку на настоящую константу
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
11.08.2011, 16:33
Цитата Сообщение от grizlik78 Посмотреть сообщение
Ага, и от указателей по той же причине отказаться.
Если Вы про встроенные указатели (T*), то, естественно, отказатся.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2011, 23:08
должны лишь константную ссылку на строку, а не просто тип string, дабы избежать ненужного копирования.
Т.е если использовать const ... & ... , будет работать быстрее?
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
11.08.2011, 23:11
Avazart, разумеется. Возвращая string, вы возвращаете объект, т.е. копируете все его данные (в том числе надо выделить память под новую строку и скопировать в неё содержимое старой). Возвращая string &, вы, по сути, возвращаете адрес.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2011, 23:57
Ну да, а const применяется что бы случайно не изменить содержание этого адреса
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
12.08.2011, 00:03
Avazart, ага, а const_cast отметает это дело, поэтому я всё-таки за возвращение копии.
1
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
12.08.2011, 07:14
Ну, с одной стороны стандарт разрешает компилятору из цепочки копирований объекта удалять очевидные. Если это относится и к случаю копирования в переменную объекта, возвращаемого из функции по значению, то это делает данный спор несколько бессмысленным. А с другой стороны итераторы STL, например, специально спроектированы так, что после изменения контейнера становятся недействительными, но из-за этого никто не призывает от них отказаться.
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
12.08.2011, 11:36
Цитата Сообщение от Mr.X Посмотреть сообщение
А с другой стороны итераторы STL, например, специально спроектированы так, что после изменения контейнера становятся недействительными, но из-за этого никто не призывает от них отказаться
Итератор становится недействительными только если элемент на который он указывал был удален или перемещен, поэтому инвалидация итератора и изменение контейнера слабо связанные события. Да и итератор, как возвращаемое значение метода, довольно редкое явление, в отличии от указателей и ссылок.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.08.2011, 11:36

Почему нехорошо себя ведёт конструктор класса (не компилится ничё), если ему параметром ссылку на константу?
То есть вообще непонятно ничё, вот, смотрите, этот пример не компилится: #include &lt;stdio.h&gt; class fee { public: //Не...

ООП - Указатели на функции члены класса
Не пойму в чем ошибка, MVS2017 при компиляции выдает целую стопку ошибок: #include &lt;iostream&gt; using namespace std ...

Массив указателей на функции-члены класса
Задача заключается в том, что в private надо создать статическую переменную символьного типа, в protected просто переменные вещественного...

Константные массивы как члены класса и ошибка Call of nonfunction
Здравствуйте. Я по двум связанным вопросам. 1) Требуется объявить константный массив как член класса. По статейки с форума rsdn (не...

Использование указателей на функции-члены внутри самого класса
День добрый форум! Возник такой вопрос. В классе А есть 3 функции и массив, в котором хранятся адреса этих функций. class A ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru