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

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

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

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

08.08.2011, 21:09. Просмотров 7357. Ответов 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 ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
soft.creator
104 / 104 / 4
Регистрация: 17.10.2010
Сообщений: 283
08.08.2011, 22:18 #2
Да, Вы правы
2
rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
08.08.2011, 22:42 #3
Цитата Сообщение от Roof Посмотреть сообщение
1) Константными эти функции должны быть, так как они не меняют значений переменных-членов объекта.
В противном случае их нельзя будет вызвать для константных объектов. Например:
C++
1
2
3
4
void func(const person& p)
{
    p.get_addres(); // ошибка, если get_addres() не является константным методом
}
Т.е. для константного this вызываются константные методы, а для неконстантного соответственно неконстантные(либо константные, если неконстантные не объявлены).
Цитата Сообщение от Roof Посмотреть сообщение
2) Возвращать они должны лишь константную ссылку на строку, а не просто тип string, дабы избежать ненужного копирования.
Да.
1
PointsEqual
ниначмуроФ
835 / 519 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
08.08.2011, 22:44 #4
Цитата Сообщение от Roof Посмотреть сообщение
Возвращать они должны лишь константную ссылку на строку, а не просто тип string, дабы избежать ненужного копирования.
Нет .
0
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
08.08.2011, 22:49 #5
Цитата Сообщение от PointsEqual Посмотреть сообщение
Нет .
почему нет? где-то на глаза мне попадалась статья где объяснялось почему в Qt отказались от возвращения ссылки на константу и возвращают просто объект, но я уж непомню детали той статьи, а ссылка утеряна
0
PointsEqual
ниначмуроФ
835 / 519 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
08.08.2011, 22:52 #6
Цитата Сообщение от Maxwe11 Посмотреть сообщение
почему нет?
потому что возвращенная ссылка может пережить свой объект.
0
Roof
154 / 154 / 10
Регистрация: 03.11.2010
Сообщений: 393
08.08.2011, 23:03  [ТС] #7
2 rangerx - твой пример проверил, действительно, так и есть. Спасибо, за информацию.
А про второй пункт мнения, гляжу, разные.
0
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
08.08.2011, 23:06 #8
кстати Roof, конструктор лучше записать так
C++
1
person( const std::string &_name, const std::string &_addres )...
Добавлено через 18 секунд
Цитата Сообщение от PointsEqual Посмотреть сообщение
потому что возвращенная ссылка может пережить свой объект.
а пример можно?
1
PointsEqual
ниначмуроФ
835 / 519 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
08.08.2011, 23:11 #9
Цитата Сообщение от Maxwe11 Посмотреть сообщение
а пример можно?
например так
C++
1
string sss = (person(s1,s2).get_name());
1
Roof
154 / 154 / 10
Регистрация: 03.11.2010
Сообщений: 393
08.08.2011, 23:11  [ТС] #10
Цитата Сообщение от Maxwe11 Посмотреть сообщение
кстати Roof, конструктор лучше записать так
C++
1
person( const std::string &_name, const std::string &_addres )...
Нну да, согласен. Ведь данный конструктор не меняет значений параметров.
0
PointsEqual
ниначмуроФ
835 / 519 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
08.08.2011, 23:23 #11
Maxwe11, если ссылка утерена, об этом можно у Мэйерса почитать (28 правило, 55сов.)
0
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
08.08.2011, 23:37 #12
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
да, но у Майерса пример с ссылкой на локальный объект
а такой код например отрабатывает
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const std::string & person::get_addres() const
{
     return addres;
}
 
const std::string & person::get_name() const
{
     return name;
}
 
int main()
{
    std::string name, addr;
 
    {
        person per(std::string("Vasya"), std::string("world"));
        name = per.get_name();
        addr = per.get_addres();
    }
 
    std::cout << name << '\n' << addr;
    return 0;
}
0
Roof
154 / 154 / 10
Регистрация: 03.11.2010
Сообщений: 393
08.08.2011, 23:40  [ТС] #13
2 PointsEqual
1) Т.е., насколько я понимаю - в методах моего класса нужно вернуть объект типа string, а не ссылку на константу?
2) Желаю разобраться, что же в этом примере "плохого".
Я его понимаю так - sss присваивается значение, возвращаемое методом get_name(), а этот метод вызвал временный объект типа person. Т.е. объект исчез, а ссылка так и осталась висеть в памяти? Если бы метод get_name() возвращал объект типа string, то этот возвращаемый объект исчезнет вместе с временным объектом типа person?
C++
1
2
3
4
string str1 = "Alexander";
string str2 = "Zelenogradsk";
string sss = ( person( str1, str2 ).get_name() );
cout << sss << endl; //выводит Alexander
Я правильно понял?
0
PointsEqual
ниначмуроФ
835 / 519 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
08.08.2011, 23:48 #14
Цитата Сообщение от Maxwe11 Посмотреть сообщение
а такой код например отрабатывает
да отрабатывает. Но все равно, я бы не стал возвращать ссылку.

Добавлено через 4 минуты
Цитата Сообщение от Roof Посмотреть сообщение
Я правильно понял?
да .
1
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
08.08.2011, 23:51 #15
Цитата Сообщение от Maxwe11 Посмотреть сообщение
name = per.get_name();
так тут обычный
string& operator= ( const string& str );
ссылка не живет дольше времени
2
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.08.2011, 23:51
Привет! Вот еще темы с ответами:

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
08.08.2011, 23:51
Ответ Создать тему
Опции темы

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