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

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

Войти
Регистрация
Восстановить пароль
 
yol
10 / 10 / 0
Регистрация: 13.10.2012
Сообщений: 155
#1

Перегрузка префиксного оператора инкремента с возвращающим значением - C++

29.01.2014, 23:52. Просмотров 425. Ответов 4
Метки нет (Все метки)

Наткнулся на интересный код. В ссылках и указателях я разбираюсь хорошо, но я вошел в ступор при рассмотрении нижеописанного примера.
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <conio.h>
 
using namespace std;
 
//Объявление класса.
class Counter
{
public:
    Counter();
    ~Counter(){}
    int GetItsVal() const {return itsVal;}
    void SetItsVal(int x) {itsVal=x;}
    const Counter* GetAddr() const {return this;}
    const Counter& operator++();
 
private:
    int itsVal;
};
 
//Определение класса.
Counter::Counter():itsVal(0)
{
    cout<<"\tВызов конструктора для ("<<this<<")"<<endl;
}
 
 
const Counter& Counter::operator++()
{
    ++itsVal;
    cout<<"\t\tУвеличил!"<<endl;
    return *this;
}
 
 
int main()
{
    setlocale(LC_ALL, "rus");
    Counter i;
    cout<<"Значение i="<<i.GetItsVal()<<endl;
    ++i;
    cout<<"Значение i="<<i.GetItsVal()<<endl;
    Counter a=++i;
    cout<<"Значение i="<<i.GetItsVal()<<endl;
    cout<<"Значение a="<<a.GetItsVal()<<endl;
    
    cout<<"Адрес (i): "<<&i<<endl;
    cout<<"Адрес (a): "<<&a<<endl;
    getch();
    return 0;
}
В строке 43 создается новый экземпляр класса - "a" и, по идеи, должен вызываться конструктор, но он не вызывается - это первый момент.

Второй момент, зачем в заголовке функции стр. 28 указывается возвращаемое значение постоянной ссылки, ведь сама по себе ссылка является и так постоянной.

Третий момент, раз возвращаемое значение функции (стр. 28) является ссылка, то почему в строке 43 создается объект класса, а не ссылка?

Для интереса, я решил вывести в конце адреса объектов, проверить не одинаковы ли они (т.е. не является ли объект a ссылкой объекта i).
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.01.2014, 23:52
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Перегрузка префиксного оператора инкремента с возвращающим значением (C++):

Перегрузка префиксного инкремента - C++
Как перегрузить префиксальный инкремент? class Horse{ private: int x,y; public: Horse(void); void setX(int); ...

Перегрузка оператора инкремента/декремента через friend - C++
Нужно реализовать перегрузку унарного оператора через friend. Что я пытаюсь сделать: friend void operator -- ();//prototype void...

Перегрузка оператора ().Выражение должно быть допустимым для изменения левосторонним значением - C++
Здравствуйте. Интересует ответ на вопрос: почему если в классе перегружен оператор без амперсанда (в моем случае () ) ,то в мейне при...

Переопределение оператора инкремента - C++
В теле класса &quot;Сlocks&quot; описали: Clocks&amp; operator ++(); // Prefix increment operator. Clocks operator ++(int); // Postfix...

Перегрузка инкремента ++ - C++
Не понимаю как вызвать перегрузку инкремента: void operator ++( int m ); в функции main,какой синтаксис. Я в main циклично ввожу числа и...

Перегрузка инкремента - C++
Допустим, что некий класс имеет в наличии методы пре(и пост-)фиксного инкрементов. Date&amp; Date::operator++(); Date...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
AnDrew_LP
160 / 162 / 9
Регистрация: 29.05.2010
Сообщений: 435
30.01.2014, 00:09 #2
В строке 43 - вызов конструктора копирования по умолчанию.
зачем в заголовке функции стр. 28 указывается возвращаемое значение постоянной ссылки, ведь сама по себе ссылка является и так постоянной.
Это не постоянная ссылка, а ссылка на константный объект. То есть, воспринимайте это так
C++
1
(const Counter)&
0
zelim
77 / 77 / 4
Регистрация: 26.12.2011
Сообщений: 217
30.01.2014, 00:35 #3
Цитата Сообщение от yol Посмотреть сообщение
В строке 43 создается новый экземпляр класса - "a" и, по идеи, должен вызываться конструктор, но он не вызывается - это первый момент.
Здесь вызывается копирующий конструктор (Counter::Counter(const Counter&)). Так как он явно не реализован, компилятор использует свою версию реализации "по умолчанию".

Цитата Сообщение от yol Посмотреть сообщение
Второй момент, зачем в заголовке функции стр. 28 указывается возвращаемое значение постоянной ссылки, ведь сама по себе ссылка является и так постоянной.
Не константная ссылка не может указывать на константный объект. Без const, по-моему, выкинет ошибку (говорю "по-моему", потому что не проверял код в действии).

Цитата Сообщение от yol Посмотреть сообщение
Третий момент, раз возвращаемое значение функции (стр. 28) является ссылка, то почему в строке 43 создается объект класса, а не ссылка?
Всё тот же копирующий конструктор.

Добавлено через 1 минуту
AnDrew_LP, опередили )
1
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
30.01.2014, 00:53 #4
Цитата Сообщение от yol Посмотреть сообщение
Второй момент, зачем в заголовке функции стр. 28 указывается возвращаемое значение постоянной ссылки, ведь сама по себе ссылка является и так постоянной.
Это означает, что возвращаемый объект по ссылке нельзя изменять, т.е. возвращается ссылка на константу.
1
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
30.01.2014, 10:03 #5
Цитата Сообщение от yol Посмотреть сообщение
Третий момент, раз возвращаемое значение функции (стр. 28) является ссылка, то почему в строке 43 создается объект класса, а не ссылка?
а почему должна быть ссылка если Вы объявили что Сounter а будет объектом
Цитата Сообщение от yol Посмотреть сообщение
C++
1
2
3
4
5
6
const Counter& Counter::operator++()
{
++itsVal;
cout<<"\t\tУвеличил!"<<endl; 
return *this;
}
если я ничего не путаю постфиксная форма вот так реализуется
C++
1
2
3
4
5
6
7
Counter Counter::operator++()
{
Counter tmp(*this);
++itsVal;
cout<<"\t\tУвеличил!"<<endl; 
return tmp;
}
а Ваша реализация болше похожа на префиксную

Добавлено через 2 минуты

Не по теме:

хотя да в теме про префиксную и написано

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.01.2014, 10:03
Привет! Вот еще темы с ответами:

Перегрузка операции инкремента - C++
Как известно, постинкремент возвращает r-value, а преинкремент - l-value. То есть: ++(++x); // допустимо (x++)++; // ошибка...

Перегрузка операторов инкремента - C++
Мне надо перегрузить инкримент, я пытался сделать постфиксный и + . Я вродебы сделал, но оно почему-то не выводит.( prog.h #pragma once...

Перегрузка постфиксной и префиксной операции инкремента - C++
Здравствуйте! У меня возник вопрос: почему выводит разный результат, казалось бы, одинаковый код Вот здесь выводит как должно: ...

Написать функцию перегрузки оператора инкремента для увеличения переменной типа enum class - C++
Доброго времени суток. Есть перечисление. enum class Month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, nov, dec }; ...


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

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

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