Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 56, средняя оценка - 4.66
Roof
154 / 154 / 10
Регистрация: 03.11.2010
Сообщений: 393
#1

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

08.08.2011, 21:09. Просмотров 7705. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.08.2011, 21:09
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Константные функции-члены класса, возвращающие ссылку на константу (C++):

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

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

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

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

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

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

64
silent_1991
Эксперт С++
5005 / 3063 / 149
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
11.08.2011, 11:02 #46
Цитата Сообщение от Сыроежка Посмотреть сообщение
На мой взгляд, это совершенно ясно
Это на ваш взгляд. А, например, на мой взгляд "избежать возможности изменять" и "неумышленно изменить" - разные вещи. Так что, как видите, вы не являетесь последней инстанцией и не уполномочены додумывать за людьми недосказанное. Пока автор не уточнил свои слова, не стоит так категорично пояснять то, как вы их поняли.
2
rangerx
1941 / 1550 / 141
Регистрация: 31.05.2009
Сообщений: 2,913
11.08.2011, 12:09 #47
Пока так и не увидел ни одного реального довода в пользу НЕиспользования константных ссылок в качестве возвращаемого значения. Пример вроде
C++
1
const string& sss = ( person( str1, str2 ).get_name() );
выглядит как-то не очень убедительно. А по поводу const_cast полностью согласен с вышесказанным:
Цитата Сообщение от Сыроежка Посмотреть сообщение
если вы умышленно меняете то, что не предназначалось для изменения, как вы предложили с помощью const_cast, то вы - вредитель.
0
easybudda
Модератор
Эксперт CЭксперт С++
9966 / 5889 / 996
Регистрация: 25.07.2009
Сообщений: 11,149
11.08.2011, 12:26 #48
Цитата Сообщение от rangerx Посмотреть сообщение
Пока так и не увидел ни одного реального довода в пользу НЕиспользования константных ссылок в качестве возвращаемого значения.
Утверждение вроде "Пользователи класса НЕ должны иметь прямого доступа к его скрытым членам" - не аргумент?

Цитата Сообщение от Deviaphan Посмотреть сообщение
Только вот некоторые бездари используют приведение типа в стиле Си
Если это на мой садовый участок кирпич, так и средствами С++ вполне можно ссылку на константный объект сделать ссылкой на неконстантный... Вообще думаю, первое, что сделает начинающий и не слишком хорошо учившийся программист при сообщении компилятора "... bla bla bla const bla bla bla..." - постарается от константности избавиться. И таки добьётся своего. Что будет дальше - загадка...
1
CyBOSSeR
Эксперт С++
2308 / 1681 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
11.08.2011, 13:14 #49
Цитата Сообщение от rangerx Посмотреть сообщение
Пока так и не увидел ни одного реального довода в пользу НЕиспользования константных ссылок в качестве возвращаемого значения.
Основная пробелама ссылок, это то что они могут пережить объект на который ссылаются. Чем не повод (наряду с соблюдением инкапсуляции) не возвращать их?
Цитата Сообщение от Сыроежка Посмотреть сообщение
Потому что если вы умышленно меняете то, что не предназначалось для изменения, как вы предложили с помощью const_cast, то вы - вредитель.
Я никого константность снимать и не призываю, я лишь указал на то, что возврат константной ссылки на внутренности объекта никак не позволит
Цитата Сообщение от lavan Посмотреть сообщение
избежать возможности изменять private часть класса без использования интерфейса
Кроме того, если вы, как разработчик класса, даете лазейку в виде применения const_cast клиентам, то это исключительно Ваша проблема, что Вы не сумели продумать дизайн, действительно исключающий возможность изменения внутреннего состояния объекта Вашего класса за его пределами.
0
grizlik78
Эксперт С++
1981 / 1474 / 127
Регистрация: 29.05.2011
Сообщений: 3,047
11.08.2011, 13:35 #50
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Основная пробелама ссылок, это то что они могут пережить объект на который ссылаются. Чем не повод (наряду с соблюдением инкапсуляции) не возвращать их?
Ага, и от указателей по той же причине отказаться. Да и вообще от C++
0
silent_1991
Эксперт С++
5005 / 3063 / 149
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
11.08.2011, 13:37 #51
grizlik78, а кто предлагал отказаться? Предлагается не возвращать ссылки на закрытые члены класса, и всего-то))
0
grizlik78
Эксперт С++
1981 / 1474 / 127
Регистрация: 29.05.2011
Сообщений: 3,047
11.08.2011, 13:48 #52
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Ну меня, по-крайней мере, не убедили.
Если пользователь случайно или намеренно меняет значения по ссылкам/указателям на константу, то он ССЗБ. Надо такому пользователью в одном из вызовов вернуть ссылку на настоящую константу, пусть попрыгает
5
silent_1991
Эксперт С++
5005 / 3063 / 149
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
11.08.2011, 14:06 #53
Цитата Сообщение от grizlik78 Посмотреть сообщение
Надо такому пользователью в одном из вызовов вернуть ссылку на настоящую константу
0
CyBOSSeR
Эксперт С++
2308 / 1681 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
11.08.2011, 16:33 #54
Цитата Сообщение от grizlik78 Посмотреть сообщение
Ага, и от указателей по той же причине отказаться.
Если Вы про встроенные указатели (T*), то, естественно, отказатся.
0
Avazart
Эксперт С++
7572 / 5557 / 326
Регистрация: 10.12.2010
Сообщений: 24,916
Записей в блоге: 17
11.08.2011, 23:08 #55
должны лишь константную ссылку на строку, а не просто тип string, дабы избежать ненужного копирования.
Т.е если использовать const ... & ... , будет работать быстрее?
0
silent_1991
Эксперт С++
5005 / 3063 / 149
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
11.08.2011, 23:11 #56
Avazart, разумеется. Возвращая string, вы возвращаете объект, т.е. копируете все его данные (в том числе надо выделить память под новую строку и скопировать в неё содержимое старой). Возвращая string &, вы, по сути, возвращаете адрес.
0
Avazart
Эксперт С++
7572 / 5557 / 326
Регистрация: 10.12.2010
Сообщений: 24,916
Записей в блоге: 17
11.08.2011, 23:57 #57
Ну да, а const применяется что бы случайно не изменить содержание этого адреса
0
silent_1991
Эксперт С++
5005 / 3063 / 149
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
12.08.2011, 00:03 #58
Avazart, ага, а const_cast отметает это дело, поэтому я всё-таки за возвращение копии.
1
Mr.X
Эксперт С++
3059 / 1704 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
12.08.2011, 07:14 #59
Ну, с одной стороны стандарт разрешает компилятору из цепочки копирований объекта удалять очевидные. Если это относится и к случаю копирования в переменную объекта, возвращаемого из функции по значению, то это делает данный спор несколько бессмысленным. А с другой стороны итераторы STL, например, специально спроектированы так, что после изменения контейнера становятся недействительными, но из-за этого никто не призывает от них отказаться.
0
CyBOSSeR
Эксперт С++
2308 / 1681 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
12.08.2011, 11:36 #60
Цитата Сообщение от Mr.X Посмотреть сообщение
А с другой стороны итераторы STL, например, специально спроектированы так, что после изменения контейнера становятся недействительными, но из-за этого никто не призывает от них отказаться
Итератор становится недействительными только если элемент на который он указывал был удален или перемещен, поэтому инвалидация итератора и изменение контейнера слабо связанные события. Да и итератор, как возвращаемое значение метода, довольно редкое явление, в отличии от указателей и ссылок.
0
12.08.2011, 11:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2011, 11:36
Привет! Вот еще темы с ответами:

Константные указатели и указатели на константу - C++
Чем они, собственно говоря, отличаются? Поясните, пожалуйста. Не знаю, как так получилось, что в разных источниках - разные...

В каких случаях компилятор делает функции-члены класса встроенными (inline)? - C++
Добрый день! Хочу спросить следующее: в интернете пишут, что если делать реализацию методов класса внутри его объявления, то такие методы...

Константные поля класса - C++
Такой вопрос, как инициализировать константные поля класса? Работают конструкции вида obj():t(0){}; который используется в примере ниже. А...

Константные статические объекты класса. - C++
Здравствуйте. Есть класс &quot;матрица&quot; нужно задать константные матрицы такие как E - единичная матрица и т.д., как это сделать? #include...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru