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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
mamucho666
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
#1

Удаляется объект когда не требуется и всё равно продолжает существовать - C++

16.07.2012, 17:07. Просмотров 1135. Ответов 24
Метки нет (Все метки)

Всем привет. Честно говоря я не знаю как ещё более правильно описать проблему в заголовке. В общем проходил раздел, посвящённый <functional>, и, собственно, там всё понятно, но заметил одну странность, потом перепроверил в специально написанном для проверки более простом коде и она подтвердилась.
Код ниже выводит на экран вот эти надписи:

ok1
ok2
delete ok1
100

delete ok2

Вопросы мои по поводу выделенных жирным.

1. Зачем удаляется объект класса ок1 до завершения функции в которой он создан?
2. Если он удалился, то откуда тогда взялся доступ к члену этого объекта?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct ok1
{
    ok1(int i):val(i){cout << "ok1" << endl;}
    int val;
    ~ok1(){cout << "delete ok1" << endl;}
};
struct ok2
{
    ok2 (ok1 & refobj):obj(refobj){cout << "ok2" << endl;}
    ok1 & obj;
    ~ok2(){cout << "delete ok2" << endl;}
};
int main()
{
    ok2 a(ok1(100));
    cout << a.obj.val << endl;
    system("pause");
    return 0;
}
P.S. Заранее благодарен.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.07.2012, 17:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Удаляется объект когда не требуется и всё равно продолжает существовать (C++):

сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь усложнять? - C++
сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь...

окно всё равно закрывается.... - C++
Всем доброго времени суток! прочитал тему тут понял что в конце программы необходимо добавить функцию getchar(); написал программку: ...

Почему удаляется объект? - C++
Помогите, пожалуйста, понять почему удаляется объект и как это исправить? Идея следующая: В Source.cpp я создаю два объекта, вызывая...

Объект удаляется до возвращения его из функции - C++
Есть следующий код перегрузки операции &quot;+&quot; для сложения матриц: Matrix operator+(const Matrix &amp;x) { Matrix result(*this); ...

удаляется ли объект или происходит утечка памяти? - C++
Добрый день, подскажите, при таком коде, удаляется ли объект или происходит утечка памяти? std::list&lt;A*&gt; entities; ...

Созданный объект Array<char> удаляется, как только метод convert завершается - C++
Есть простенькая оболочка над массивом Array&lt;T&gt;: template&lt;typename T&gt; class Array { private: T* data; public: const...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
soon
2540 / 1305 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:44 #16
ForEveR, я поэтому и просил, чтобы компилил именно ТС. MSVC12, ведь, уже обзавелась rvalue-reference? Так вот, если в конструкторе & изменить на &&, то вывод на g++ 4.7.1 будет тоже 5
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
16.07.2012, 18:45 #17
Да-с, нарушение стандарта. 1>c:\users\forever\documents\visual studio 11\projects\consoleapplication1\consoleapplication1\create.cpp(22): warning C4239: нестандартное расширение: аргумент: преобразование "ok1" в "ok1 &"
К слову 10-ка тоже была с rvalue-ref насколько я помню.
soon
2540 / 1305 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:56 #18
Цитата Сообщение от ForEveR Посмотреть сообщение
К слову 10-ка тоже была с rvalue-ref насколько я помню.
Похоже, да, wiki тоже об этом говорит.
mamucho666
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
16.07.2012, 19:01  [ТС] #19
Вы меня просите о чём я понятия не имею. Что значит изменить refobj?
Если вы не против, скиньте мне просто готовый код, который надо скомпилить.

У меня пока вопрос возник, почему в коде ok(a) выдаёт ошибку, при чём вообще непонятную
(
(11): error C2371: a: переопределение; различные базовые типы
(10): см. объявление "a"
(11): error C2512: ok: нет подходящего конструктора по умолчанию),
)
а создание именованного объекта ok b(a) проходит успешно?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct ok
{
    ok(int i):val(i){cout << "ok" << endl;}
    int val;
    ~ok(){cout << "delete ok" << endl;}
};
int main()
{
    int a(100);
    ok(a);
    ok b(a);
    system("pause");
    return 0;
}
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
16.07.2012, 19:05 #20
soon, Даже стало интересно, как-то вообще можно проверить каким образом компилятор делает такое корректным? По сути тест case какой-то такой

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
 
using namespace std;
 
void value(string& value)
{
}
 
int main()
{
    value(string());
}
Кстати, для примитивных типов, это не работает (int etc.).

Добавлено через 53 секунды
C++
1
ok(a);
Объявление объекта a типа ok, а не то что вы хотели.
mamucho666
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
16.07.2012, 19:13  [ТС] #21
В общем я наверно пока закрою на это глаза и продолжу изучать дальше, всем огромное спасибо, может где-то это описано в книге. Липпман - C++ Primer, если кому интересно.

P.S. Кстати вот такая запись почему-то работает
int a(100);
ok::ok(a);

Наверно при использовании
int a(100);
ok(a); имеется ввиду что-то другое.
soon
2540 / 1305 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 19:21 #22
ForEveR, эх, был бы онлайн компилер MSVC...
Раз по стандарту может быть только const & или &&, следовательно надо проверять на MSVC 08(если, конечно, он не поддерживает rvalue-ссылки).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
 
using namespace std;
 
void value(string& value)
{
    value = "42";
}
 
int main()
{
    value(string());
}
Если прокатит, то MSVC идет вразрез со стандартом, причем дело не ограничивается кастованием к const. Ну и почему не получается с примитивными типами - брр
Еще была идея скомпилировать с const и &&, а потом сравнить ассемблерный листинг. Может получится.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
16.07.2012, 20:07 #23
Код который был.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
00A53500  push        0A5CBB8h  
00A53505  lea         ecx,[ebp-0F0h]  
00A5350B  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (0A513A7h)  
00A53510  mov         dword ptr [ebp-0F8h],eax  
00A53516  mov         eax,dword ptr [ebp-0F8h]  
00A5351C  mov         dword ptr [ebp-0FCh],eax  
00A53522  mov         dword ptr [ebp-4],0  
00A53529  mov         ecx,dword ptr [ebp-0FCh]  
00A5352F  push        ecx  
00A53530  call        value (0A5143Dh)  
00A53535  add         esp,4  
00A53538  mov         dword ptr [ebp-4],0FFFFFFFFh  
00A5353F  lea         ecx,[ebp-0F0h]  
00A53545  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (0A512BCh)
rvalue.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
00CD3500  push        0CDCBB8h  
00CD3505  lea         ecx,[ebp-0F0h]  
00CD350B  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (0CD13A7h)  
00CD3510  mov         dword ptr [ebp-0F8h],eax  
00CD3516  mov         eax,dword ptr [ebp-0F8h]  
00CD351C  mov         dword ptr [ebp-0FCh],eax  
00CD3522  mov         dword ptr [ebp-4],0  
00CD3529  mov         ecx,dword ptr [ebp-0FCh]  
00CD352F  push        ecx  
00CD3530  call        value (0CD1442h)  
00CD3535  add         esp,4  
00CD3538  mov         dword ptr [ebp-4],0FFFFFFFFh  
00CD353F  lea         ecx,[ebp-0F0h]  
00CD3545  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (0CD12BCh)
const.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
00A93500  push        0A9CBB8h  
00A93505  lea         ecx,[ebp-0F0h]  
00A9350B  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (0A913A7h)  
00A93510  mov         dword ptr [ebp-0F8h],eax  
00A93516  mov         eax,dword ptr [ebp-0F8h]  
00A9351C  mov         dword ptr [ebp-0FCh],eax  
00A93522  mov         dword ptr [ebp-4],0  
00A93529  mov         ecx,dword ptr [ebp-0FCh]  
00A9352F  push        ecx  
00A93530  call        value (0A91447h)  
00A93535  add         esp,4  
00A93538  mov         dword ptr [ebp-4],0FFFFFFFFh  
00A9353F  lea         ecx,[ebp-0F0h]  
00A93545  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (0A912BCh)
Похоже, все три варианта дают одинаковый асм код
soon
2540 / 1305 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 20:13 #24
ForEveR, а в MSVC есть флаги оптимизации?
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
16.07.2012, 20:50 #25
soon, Ага. Это все O0.

Добавлено через 29 минут
http://stackoverflow.com/questions/1...tudio#11508812
Или скорее даже как-то так... Тот ответ который я принял кажется более логичным.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.07.2012, 20:50
Привет! Вот еще темы с ответами:

После удаления (перезаписи) данных из бинарного файла, файл всё равно существует, несмотря на то, что он пуст - C++
после удаления(перезаписи) данных из бинарного файла, файл всё равно существует, как сделать так чтобы и файл удалялся если он пустой?

Зачем нужно освобождать память динамических объектов в деструкторе, если всё равно это сделает менеджер памяти - C++
Не скажу за все ОС-и, но под Windows есть менеджер памяти. Когда по ходу кода встречается new, ну или что - то другое для алокации...

Почему процесс продолжает существовать после закрытия окна? - VBA
1. К MS Access 2000 подключил COM Add-in написанный на VBA. При соединении Add-in'а вызывается функция addin_onconnection с параметрами,...

Домен после удаления продолжает существовать, как его удалить? - RedHat, Fedora Linux
Я слаб в линуксе, обычно все делаю через админ-панель. Тут заметил, что Яндекс видит один из веб-сайтов под вообще другим доменом, который...


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

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

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