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

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

Войти
Регистрация
Восстановить пароль
 
_Eldar_
44 / 29 / 3
Регистрация: 31.10.2009
Сообщений: 200
#1

Конструкторы и деструкторы функционального объекта - C++

03.07.2010, 12:33. Просмотров 719. Ответов 6
Метки нет (Все метки)

Привет всем. Вообщем разбирал задачу, в которой рассматривается алгоритм for_each, я решил добавить отладочный вывод в конструктор и деструктор чтобы посмотреть сколько раз они вызываются и честно говоря результат меня удивил
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
#include <iostream>
#include <algorithm>
 
using namespace std;
 
class display{
private:
    int i;
public:
    display(): i(0){ cout << "Constructor " << endl;}
    ~display(){cout << "Destructor " << endl;}
    void operator()(int x){
        cout << "a[" << i++ << "] = " << x << endl;
    }
};
 
int main(){
    const int N = 4;
    int a[N] = {7, 6, 9, 2};
    for_each(a, a + N, display());
    for_each(a, a + N, display());
    
    return 0;
}
кто-нибудь может объяснить почему вызывается один конструктор и 3 деструктора? (в данном конкретном случае)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Somebody
2778 / 1592 / 142
Регистрация: 03.12.2007
Сообщений: 4,175
Завершенные тесты: 1
03.07.2010, 17:10     Конструкторы и деструкторы функционального объекта #2
Создаются объекты ещё конструктором копирования.
C++
1
display(const display&) { cout << "Copy Constructor " << endl;}
В g++/Dev-C++ попробовал - 1 создание, 1 копирование, 2 деструктора. Так понимаю, что создаётся в display(), потом копируется первый раз при передаче в функцию for_each по значению, второй раз в return'е из for_each (она же возвращает свой 3-й параметр). Количество вызовов конструкторов/деструкторов при возврате из функции в общем может зависеть от уровня оптимизации. Где тут может появиться ещё одно копирование, точно не знаю.
Далее чисто догадки. Например, если в for_each что-то типа
C++
1
2
3
4
5
6
for_each(,,f)
{
t = f;
for (...) f(...);
return t;
}
то тут может быть копирование в t = f.
Однако, запуск варианта с
C++
1
for_each(a, a + N, display())(999)
и вывод a[2009226388] = 999 О_о подсказывает, что тут что-то интереснее.
Nick Alte
Эксперт С++
1605 / 997 / 118
Регистрация: 27.09.2009
Сообщений: 1,923
Завершенные тесты: 1
03.07.2010, 17:28     Конструкторы и деструкторы функционального объекта #3
Цитата Сообщение от Somebody Посмотреть сообщение
Количество вызовов конструкторов/деструкторов при возврате из функции в общем может зависеть от уровня оптимизации.
Строго говоря, это неверно. Другое дело, что хороший оптимизатор зачастую довольно хорошо выкидывает ненужные команды из получившейся последовательности вызовов, особенно когда имеем дело с несложными объектами и тривиальными конструкторами-деструкторами.
Тем не менее, если мы определим "стучащие" конструкторы-деструкторы для какого-то объекта, который передаём в функцию по значению, да и вообще проделываем с ним разные интересные манипуляции, то полученный отчёт о последовательности операций не будет отличаться для отладочного варианта, в котором полностью отключена оптимизация, и для релиза, какие настройки оптимизации в нём ни выставляй.
_Eldar_
44 / 29 / 3
Регистрация: 31.10.2009
Сообщений: 200
04.07.2010, 04:24  [ТС]     Конструкторы и деструкторы функционального объекта #4
Добавил конструктор копирования
C++
1
display(display& ) {cout << "Copy constructor" << endl;}
теперь Вызываются 2 конструктора (1 обычный, 1 копирования), и 2 деструктора. Убираю конструктор копирования - вызывается один конструктор и 3 деструктора. Окончательно запутался
Somebody
2778 / 1592 / 142
Регистрация: 03.12.2007
Сообщений: 4,175
Завершенные тесты: 1
04.07.2010, 11:59     Конструкторы и деструкторы функционального объекта #5
Цитата Сообщение от Nick Alte Посмотреть сообщение
Тем не менее, если мы определим "стучащие" конструкторы-деструкторы для какого-то объекта, который передаём в функцию по значению, да и вообще проделываем с ним разные интересные манипуляции, то полученный отчёт о последовательности операций не будет отличаться для отладочного варианта, в котором полностью отключена оптимизация, и для релиза, какие настройки оптимизации в нём ни выставляй.
Это почему это? Некоторые копирования при оптимизации можно убрать, это разрешено:
http://www.open-std.org/jtc1/sc22/op...tml#class.copy
Whenever a class object is copied and the original object and the copy
have the same type, if the implementation can prove that either the
original object or the copy will never again be used except as the
result of an implicit destructor call (_class.dtor_), an implementa-
tion is permitted to treat the original and the copy as two different
ways of referring to the same object and not perform a copy at all.
In that case, the object is destroyed at the later of times when the
original and the copy would have been destroyed without the
optimization.
И пример
http://en.wikipedia.org/wiki/Return_value_optimization
Nick Alte
Эксперт С++
1605 / 997 / 118
Регистрация: 27.09.2009
Сообщений: 1,923
Завершенные тесты: 1
04.07.2010, 12:57     Конструкторы и деструкторы функционального объекта #6
Можно убирать копирования, но не вызовы конструктора копирования. То есть, если у нас в конструкторе и деструкторе выполняются какие-то дополнительные действия (например, вывод диагностических сообщений), эти действия будут выполнены в одном и том же порядке независимо от оптимизации. Другое дело, что сами операции копирования при этом успешно могут быть заоптимизированы "в нуль".
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.07.2010, 21:37     Конструкторы и деструкторы функционального объекта
Еще ссылки по теме:

C++ Списки, конструкторы, деструкторы
C++ Конструкторы и деструкторы
Конструкторы и деструкторы C++
C++ Конструкторы и деструкторы
Конструкторы и деструкторы C++

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

Или воспользуйтесь поиском по форуму:
Somebody
2778 / 1592 / 142
Регистрация: 03.12.2007
Сообщений: 4,175
Завершенные тесты: 1
04.07.2010, 21:37     Конструкторы и деструкторы функционального объекта #7
Цитата Сообщение от Nick Alte Посмотреть сообщение
Можно убирать копирования, но не вызовы конструктора копирования. То есть, если у нас в конструкторе и деструкторе выполняются какие-то дополнительные действия (например, вывод диагностических сообщений), эти действия будут выполнены в одном и том же порядке независимо от оптимизации. Другое дело, что сами операции копирования при этом успешно могут быть заоптимизированы "в нуль".
Хотя, действительно, строчки стандарта какие-то мутные и прямо явно такого не говорят, но тогда на фига в стандарте всё это? Оптимизация с сохранением всех побочных эфеектов и без этого возможна, а здесь как раз говорится, что можно убрать копирование (вместе с конструктором копирования, естественно).
Yandex
Объявления
04.07.2010, 21:37     Конструкторы и деструкторы функционального объекта
Ответ Создать тему
Опции темы

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