Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/29: Рейтинг темы: голосов - 29, средняя оценка - 4.83
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602

Зачем нужен operator++(int)

30.03.2017, 13:45. Показов 6540. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Очень тупой вопрос - для чего нужен operator++(int)? Ну, то есть, понятно что он делает постинкремент. Непонятно почему этот инкремент не делает сам компилятор, на основе operator++().
C++
1
2
3
4
5
6
7
//Ну что здесь можно написать кроме этого? А если ничего, так почему компилятор за меня не напишет?
MyType operator++(int)
{
    MyType temp(*this);
    ++*this;
    return temp;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.03.2017, 13:45
Ответы с готовыми решениями:

Зачем биты нужны это меньше байтов но int 32 бита но я не допер зачем это нужно это 4 байта то есть int не может больше 4 байт весить?
Вот еще один вопрос зачем биты нужны это меньше байтов но int 32 бита но я не допер зачем это нужно это 4 байта то есть int не может...

operator char() или operator int()
Здорова госпдо! Снова ничо не ясно как всегда. Разбираю программку из книги Страуструпа, там он описывает класс String в нем есть ...

Зачем преобразовывать itsVal в int, если эта переменная и так объявлена как тип int
// Оператор преобразования #include <iostream> using namespace std; class Counter { public: Counter(): itsVal(0) {} ...

34
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
31.03.2017, 02:07
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Renji Посмотреть сообщение
Непонятно почему этот инкремент не делает сам компилятор, на основе operator++().
Во-первых, постфиксный ++ - это отдельный самостоятельный оператор, который может быть перегружен отдельно совершенно произвольным образом, никак не связанным с префиксным ++.

Во-вторых, даже если семантика этих операторов согласована, все равно это не означает, что такая реализация является правильной/осмысленной реализацией постфиксного ++. Например, для итераторов категории Input Iterator старое значение итератора вообще не имеет смысла (оно сразу "протухает"), т.е. пытаться сохранять его нельзя. Однако постинкремент такие итераторы обязаны поддерживать, чтобы работать в рамках generic алгоритмов, реализованных в терминах постинкремента (наример, использующих *it++).

Во-третьих, даже если постфиксный ++ имеет "ожидамое" поведение, реализация его вышеприведеным способом через префиксный ++ совсем не обязательно наиболее оптимальна.

Можно было бы предлоджить генерировать такую реализацию в ответ на

C++
1
MyType operator++(int) = default;
но не более того.
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
31.03.2017, 02:28
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Можно было бы предлоджить генерировать такую реализацию в ответ на
C++
1
MyType operator++(int) = default;
но не более того.
Я выше писал про операторы сравнения. Если они при перегрузке сохраняют свой смысл, то для компилятора определить все остальные из < и == - это просто заменить одну инструкцию. С инкрементами и составными операторами присваивания немного сложнее. Однако, объем "лишнего" кода, необходимого для описания всех сочетаний операторов немного удручает.
Поэтому, ИМХО, было бы удобнее по умолчанию их определять. Ошибки, которые несет неявное определение мне не очевидны, в отличии от ошибок, которые несет простыня "лишнего" кода.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
31.03.2017, 10:51
Давайте так ещё попробуем
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
#include <iostream>
using namespace std;
struct Nopostf_inc{
int a;
Nopostf_inc(int a_=0):a(a_){}
 
Nopostf_inc &operator++(){
a++;
return *this;
}
 
//////////////////////////////////
Nopostf_inc operator++(int){//это определение лучше убрать
Nopostf_inc retObj=Nopostf_inc(*this);
++(*this);
return retObj;
}
//////////////////////////////////
private:
Nopostf_inc(const Nopostf_inc & rhs);
};
 
int main(int argc, char* argv[])
{
Nopostf_inc a(5);
//a++; это вызывает ошибку выполнения ! То есть лучше закомментировать определение постфиксного инкремента
cout<<++a.a<<endl;//6
system("pause");
return 0;
}
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.03.2017, 11:26
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Можно было бы предлоджить генерировать такую реализацию в ответ на
чисто технически, с точки зрения дизайна, компилятору
ничего не мешает самостоятельно генерить дефолтную версию.
это как с конструктором копии: если нужно запретить - не вопрос.
если нужно кастомизировать - определяем явно.
дефолтная же версия устроит, пожалуй,
в 90% всех остальных случаях.

могли бы получить годный такой сахарок.

вот только нужно это при изготовлении каких нибудь кастомных итераторов,
достаточно редкая задачка, что бы ради неё вносить правки в стандарт,
и core-language
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
31.03.2017, 11:39
Цитата Сообщение от hoggy Посмотреть сообщение
чисто технически, с точки зрения дизайна, компилятору
ничего не мешает самостоятельно генерить дефолтную версию.
hoggy, а как быть с ошибкой выполнения когда нет конструктора копии? Компилятор сам придумает как копировать объект?
Или конструктор копии есть но он закрыт. То есть, члены его используют, потому что знают когда и как это можно делать. Нужен он им. А для оператора post++ он не годится. А компилятор возьмёт да и использует его. Он же не будет анализировать код, чтобы понять, что Вы этого не хотели.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.03.2017, 12:06
Цитата Сообщение от IGPIGP Посмотреть сообщение
а как быть с ошибкой выполнения когда нет конструктора копии?
это будет ошибка компиляции.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
31.03.2017, 12:32
Цитата Сообщение от hoggy Посмотреть сообщение
это будет ошибка компиляции.
у-упс. Да - ошибся. При компиляции.
Но не суть.
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
#include <iostream>
using namespace std;
struct Nopostf_inc{
int a;
Nopostf_inc(int a_=0):a(a_){}
 
Nopostf_inc &operator++(){
a++;
return *this;
}
 
//////////////////////////////////
Nopostf_inc operator++(int){
Nopostf_inc retObj=Nopostf_inc(*this);
++(*this);
return retObj;
}
//////////////////////////////////
private:
    Nopostf_inc(const Nopostf_inc & rhs):a(rhs.a){}//вот добавил определение
    //и всё заработало
    //разве нужно, чтобы оно само без определения Nopostf_inc operator++(int)
    //генерило постинкремент ??
};
 
int main(int argc, char* argv[])
{
Nopostf_inc a(5);
a++;//теперь оно работает. Но потому что мы явно это пределили
cout<<a.a; 
cout<<++a.a<<endl;//6
system("pause");
return 0;
}
1
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
31.03.2017, 12:36
Кстати, а ведь IGPIGP прав, что будет, если компилятор будет генерировать этот оператор, но при этом в классе не будет реализован явно конструктор копирования, но будет использоваться динамическое выделение памяти с освобождением в деструкторе, или вообще будет удален конструктор копирования, или будет объявлен, но реализован неправильно?
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
31.03.2017, 12:41
Вот! только вот тут чуть не понял Вас:
Цитата Сообщение от GbaLog- Посмотреть сообщение
но реализован неправильно
лучше - "не для употребления в постинкременте". imho
Потому как если что-то объявлено и определено неправильно это не проблема компилятора.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.03.2017, 12:43
Цитата Сообщение от GbaLog- Посмотреть сообщение
не будет реализован явно конструктор копирования
если объект умеет копироваццо - все норм.
если нет - ошибка компиляции.
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
31.03.2017, 12:55
Цитата Сообщение от hoggy Посмотреть сообщение
если объект умеет копироваццо - все норм.
если нет - ошибка компиляции.
тут всё понятно, но!
что если программист решил реализацию конструктора копирования положить на компилятор, ибо он явно их нигде не использует и они ему вообще не нужны, и не реализовал их, но при этом в классе используется работа с дин. памятью и освобождением в деструкторе? может получиться так:
http://rextester.com/GISF27475
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
//g++  5.4.0
 
#include <iostream>
 
struct A
{
    A() : p(new int) { std::cout << "ctor\n"; }
    ~A() { std::cout << "dtor\n"; delete p; }
    
    A & operator++()
    {
        ++*p;
        return *this;
    }
    
    A operator++(int)
    {
        A ret(*this);
        ++*this;
        return ret;
    }
    
    int * p;
};
 
int main()
{
    std::cout << "Hello, world!\n";
    
    A a;
    
    {
        a++;
    }
}
программист создал UB, сам того не подозревая.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.03.2017, 13:35
Цитата Сообщение от GbaLog- Посмотреть сообщение
программист создал UB, сам того не подозревая.
совершенно верно.

впрочем, годный компилятор услужливо намекнёт,
чем чревато нарушение правило трёх:

http://rextester.com/XRMH80806

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
#include <iostream>
#include <string>
#include <vector>
 
//-std=c++14 -fopenmp -O2 -g3 -pedantic -Wall -Weffc++ -Wextra 
//-Woverloaded-virtual -Wctor-dtor-privacy -Wnon-virtual-dtor 
//-Wold-style-cast -Wconversion -Wsign-conversion -Winit-self 
//-Wunreachable-code
 
 
#include <iostream>
 
struct A
{
    A() : p(new int) { std::cout << "ctor\n"; }
    ~A() { std::cout << "dtor\n"; delete p; }
    
    A & operator++()
    {
        ++*p;
        return *this;
    }
    
    A operator++(int)
    {
        A ret(*this);
        ++*this;
        return ret;
    }
    
    int * p;
};
 
int main()
{
    std::cout << "Hello, world!\n";
    
    A a;
    
    {
        a++;
    }
}
выхлоп:
Code
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
52
53
54
55
56
57
58
59
Warning(s):
source_file.cpp:13:8: warning: ‘struct A’ has pointer data members [-Weffc++]
 struct A
        ^
source_file.cpp:13:8: warning:   but does not override ‘A(const A&)[-Weffc++]
source_file.cpp:13:8: warning:   or ‘operator=(const A&)[-Weffc++]
Error(s):
*** Error in `/var/www/service/usercode/1643548341/a.out': double free or corruption (fasttop): 0x0000000001720c30 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f644f84a7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7fe0a)[0x7f644f852e0a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f644f85698c]
/var/www/service/usercode/1643548341/a.out[0x400933]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f644f7f3830]
/var/www/service/usercode/1643548341/a.out[0x4009a9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 b6:2bae1 3930651                         /var/www/service/usercode/1643548341/a.out
00600000-00601000 r--p 00000000 b6:2bae1 3930651                         /var/www/service/usercode/1643548341/a.out
00601000-00602000 rw-p 00001000 b6:2bae1 3930651                         /var/www/service/usercode/1643548341/a.out
0170e000-01740000 rw-p 00000000 00:00 0                                  [heap]
7f6448000000-7f6448021000 rw-p 00000000 00:00 0 
7f6448021000-7f644c000000 ---p 00000000 00:00 0 
7f644f2b4000-7f644f2ca000 r-xp 00000000 b6:2bae1 105                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f644f2ca000-7f644f4c9000 ---p 00016000 b6:2bae1 105                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f644f4c9000-7f644f4ca000 rw-p 00015000 b6:2bae1 105                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f644f4ca000-7f644f5d2000 r-xp 00000000 b6:2bae1 10854                   /lib/x86_64-linux-gnu/libm-2.23.so
7f644f5d2000-7f644f7d1000 ---p 00108000 b6:2bae1 10854                   /lib/x86_64-linux-gnu/libm-2.23.so
7f644f7d1000-7f644f7d2000 r--p 00107000 b6:2bae1 10854                   /lib/x86_64-linux-gnu/libm-2.23.so
7f644f7d2000-7f644f7d3000 rw-p 00108000 b6:2bae1 10854                   /lib/x86_64-linux-gnu/libm-2.23.so
7f644f7d3000-7f644f992000 r-xp 00000000 b6:2bae1 10849                   /lib/x86_64-linux-gnu/libc-2.23.so
7f644f992000-7f644fb92000 ---p 001bf000 b6:2bae1 10849                   /lib/x86_64-linux-gnu/libc-2.23.so
7f644fb92000-7f644fb96000 r--p 001bf000 b6:2bae1 10849                   /lib/x86_64-linux-gnu/libc-2.23.so
7f644fb96000-7f644fb98000 rw-p 001c3000 b6:2bae1 10849                   /lib/x86_64-linux-gnu/libc-2.23.so
7f644fb98000-7f644fb9c000 rw-p 00000000 00:00 0 
7f644fb9c000-7f644fbb4000 r-xp 00000000 b6:2bae1 10855                   /lib/x86_64-linux-gnu/libpthread-2.23.so
7f644fbb4000-7f644fdb3000 ---p 00018000 b6:2bae1 10855                   /lib/x86_64-linux-gnu/libpthread-2.23.so
7f644fdb3000-7f644fdb4000 r--p 00017000 b6:2bae1 10855                   /lib/x86_64-linux-gnu/libpthread-2.23.so
7f644fdb4000-7f644fdb5000 rw-p 00018000 b6:2bae1 10855                   /lib/x86_64-linux-gnu/libpthread-2.23.so
7f644fdb5000-7f644fdb9000 rw-p 00000000 00:00 0 
7f644fdb9000-7f644ff2b000 r-xp 00000000 b6:2bae1 3213                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f644ff2b000-7f645012b000 ---p 00172000 b6:2bae1 3213                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f645012b000-7f6450135000 r--p 00172000 b6:2bae1 3213                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f6450135000-7f6450137000 rw-p 0017c000 b6:2bae1 3213                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f6450137000-7f645013b000 rw-p 00000000 00:00 0 
7f645013b000-7f6450161000 r-xp 00000000 b6:2bae1 10838                   /lib/x86_64-linux-gnu/ld-2.23.so
7f645032c000-7f6450332000 rw-p 00000000 00:00 0 
7f645035d000-7f6450360000 rw-p 00000000 00:00 0 
7f6450360000-7f6450361000 r--p 00025000 b6:2bae1 10838                   /lib/x86_64-linux-gnu/ld-2.23.so
7f6450361000-7f6450362000 rw-p 00026000 b6:2bae1 10838                   /lib/x86_64-linux-gnu/ld-2.23.so
7f6450362000-7f6450363000 rw-p 00000000 00:00 0 
7fff4009e000-7fff400b3000 rw-p 00000000 00:00 0                          [stack]
7fff4014c000-7fff4014e000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
 
Abort signal from abort(3) (SIGABRT)
Hello, world!
ctor
dtor
dtor
и подобного рода косяки не имеют ни малейшего отношения,
ни к особенностям авто генерации конструкторов,
ни к теоретической возможной особенности автогенерации операторов инкремента.
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
31.03.2017, 13:42
Цитата Сообщение от hoggy Посмотреть сообщение
и подобного рода косяки не имеют ни малейшего отношения,
ни к особенностям авто генерации конструкторов,
ни к теоретической возможной особенности автогенерации операторов инкремента.
они имеют отношение только к криворукости программиста, так?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.03.2017, 13:48
Цитата Сообщение от GbaLog- Посмотреть сообщение
они имеют отношение только к криворукости программиста, так?
ага
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
31.03.2017, 14:26
Цитата Сообщение от GbaLog- Посмотреть сообщение
они имеют отношение только к криворукости программиста, так?
Не думаю. Правила для того, чтобы уметь их нарушать. У синглтона правило 3-х не работает и его конструктор копий нельзя использовать.
Но да, если программист создал владельца сложных ресурсов и "возложил" на компилятор, то правило взаимности гласит что как аукнется, так и откликнется. То есть, всё будет возложено обратно. И это будет справедливо.imho
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.03.2017, 14:26

перегрузить operator()(int,int);
#define _CRT_SECURE_NO_WARNINGS #include &lt;iostream&gt; #include &lt;locale&gt; using namespace std; class String { char...

error: invalid operands of types 'const int*' and 'const int*' to binary 'operator+'
Что означает ошибка в 8 строчке error: invalid operands of types 'const int*' and 'const int*' to binary 'operator+'? ...

Operator int() в классе Строка
Приведите пример, пожалуйста, как воспользоваться данной перегрузкой операции в main. String.h class String { private: ...

operator int() что за зверь?
Несколько раз видел в интернетах такую запись: operator int(){}; По контексту так и не понял, что это такое, да и в литературе не...

invalid operands of types 'double' and 'int' to binary 'operator%'
В строке где If выдает вот эту ошибку 2 раза: invalid operands of types 'double' and 'int' to binary 'operator%' #include...


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

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Модель по догадкам
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, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru