Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
1

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

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

Author24 — интернет-сервис помощи студентам
Всем привет. Честно говоря я не знаю как ещё более правильно описать проблему в заголовке. В общем проходил раздел, посвящённый <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. Заранее благодарен.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.07.2012, 17:07
Ответы с готовыми решениями:

Confirm - при нажатии на cancel объект всё равно удаляется
Всем добрый вечер, Помогите пожалуйста найти решение по такому вопросу: При нажатии на...

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

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

Когда делаю Float left пропадает фон у родительского элемента, точнее он есть но браузеру на него все равно
Вобщем верстал футер он у меня должен быть вот таким пока он у меня вот такой но как только...

24
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2012, 17:10 2
C++
1
ok2 a(ok1(100));
Вы создаете объект ok2 передавая ссылку на временный объект, после передачи ссылки, объект удаляется, это UB если я не ошибаюсь.
0
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
16.07.2012, 17:32  [ТС] 3
То есть аргументы удаляются так же как и параметры? Не знал, хотя догадывался. Но это можно принять. Остаётся вопрос - почему я всё равно могу пользоваться объектом?
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 17:49 4
mamucho666, это вообще компилируется? В конструктор вы передаете временный объект, хотя он должен принимать ссылку.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2012, 17:52 5
mamucho666, Всмысле удаляются так же как параметры? Что происходит в вашем коде.
1) Вызывается конструктор ok1.
2) Вызывается конструктор ok2 и передается ссылка на ранее созданный ok1.
3) Так как объект ok1 временный - вызывается деструктор ok1.

Следовательно ok2 уже не должен обращаться к этим данным, т.к. иначе это undefined behaviour.
И кстати внятный компилятор скажет об этом, пример - http://liveworkspace.org/code/... 05f3208eb3
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:15 6
ИМХО, никакого UB тут нет. Временный объект - rvalue. Ссылочный объект - lvalue. Как ТС хочет, чтобы rvalue преобразовалось в lvalue?
1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2012, 18:18 7
soon, На самом деле да, я ступил, но вопрос почему у ТС это компилируется, ведь раз он показывает вывод - значит он смог это запустить.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:23 8
ForEveR, я вначале даже подумал, что ТС переписывал код на форум вручную и вместо rvalue reference написал просто reference. В таком случае, вывод действительно будет как у ТС.
0
1 / 1 / 0
Регистрация: 06.06.2012
Сообщений: 13
16.07.2012, 18:28  [ТС] 9
Компилятор майкрософтовский, 2010. И да, soon прав.

Наверно компилятор как-то сам исправил, но он даже предупреждения не выдаёт(

А можно как-то посмотреть во что он превратил код? То есть посмотреть какую-то информацию о том что сейчас в программе происходит? Что создаётся, что удаляется и тд и тп.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2012, 18:30 10
О как. В 2012 RC студии оно тоже работает и дает тот же вывод что у ТС.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
16.07.2012, 18:33 11
поставте уровень ворнингов проекта на максимум. вот что 2008 студия выдает:
warning C4239: nonstandard extension used : 'argument' : conversion from 'Obj' to 'Obj &' A non-const reference may only be bound to an lvalue
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:36 12
Но это же бред. Временный объект может кастоваться разве что в const & и &&. ТС, ForEveR, попробуйте скомпилить это
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
#include <iostream>
 
using namespace std;
 
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;
 
    void setOk1(const ok1& k)
    {
        obj = k
    }
 
    ~ok2(){cout << "delete ok2" << endl;}
};
int main()
{
    ok2 a(ok1(100));
    cout << a.obj.val << endl;
    ok1 k(1);
    a.setOk1(k);
    // system("pause");
    return 0;
}
Может он ссылку в const запихивает.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2012, 18:36 13
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>
 
using std::cout;
using std::endl;
 
struct ok1
{
    ok1(int i):val(i){cout << "ok1" << endl;}
    int val;
    ~ok1(){cout << "delete ok1" << endl;}
};
struct ok2
{
    ok2 (volatile ok1 & refobj):obj(const_cast<ok1&>(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;
}
Ошибка 1 error C2664: ok2::ok2(volatile ok1 &): невозможно преобразовать параметр 1 из "ok1" в "volatile ok1 &" c:\users\forever\documents\visual studio 11\projects\consoleapplication1\consoleapplication1\create.cpp 20 1 ConsoleApplication1

А вот так он дает то что нужно, сдается мне что он вместо ссылки поставляет rvalue-ссылку или const-ссылку.

soon, твой код откомпилировался.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:42 14
Цитата Сообщение от ForEveR Посмотреть сообщение
А вот так он дает то что нужно, сдается мне что он вместо ссылки поставляет rvalue-ссылку или const-ссылку.
Хм. Тогда, ТС, попробуйте изменить refobj в конструкторе.

Добавлено через 2 минуты
Хотя все равно не понятно, как он const & будет преобразовывать в &, поскольку не известно, что находится pз const &. Если все пройдет гладко - налицо нарушение стандарта. На это указывает, кстати, и вывод DU
Цитата Сообщение от DU Посмотреть сообщение
nonstandard extension
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2012, 18:42 15
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
#include <iostream>
 
using namespace std;
 
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; refobj.val = 5;}
    ok1 & obj;
 
    ~ok2(){cout << "delete ok2" << endl;}
};
 
int main()
{
    ok2 a(ok1(100));
    cout << a.obj.val << endl;
    return 0;
}
Вывод 5.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:44 16
ForEveR, я поэтому и просил, чтобы компилил именно ТС. MSVC12, ведь, уже обзавелась rvalue-reference? Так вот, если в конструкторе & изменить на &&, то вывод на g++ 4.7.1 будет тоже 5
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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 насколько я помню.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.07.2012, 18:56 18
Цитата Сообщение от ForEveR Посмотреть сообщение
К слову 10-ка тоже была с rvalue-ref насколько я помню.
Похоже, да, wiki тоже об этом говорит.
0
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;
}
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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, а не то что вы хотели.
0
16.07.2012, 19:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.07.2012, 19:05
Помогаю со студенческими работами здесь

Говорит что объект есть, но в коде точно видно что объект удаляется
Добрый день. Вот небольшой пример кода. IF NOT OBJECT_ID('tempdb..#TMP_1') IS NULL DROP TABLE...

Объект браузера продолжает хранить старую версию загруженного файла
Проблема в том, что в пределах одной функции(button1_Click()), после изменения файла, объект...

Не удаляется объект
Доброго времени суток, в коде я удаляю объект, и сразу же добавляю вместо него другой, но проблема...

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

Не удаляется объект из памяти
Здравствуйте! У меня возникла следующая проблема: Мне нужно сделать форму, на которой бы...

Не удаляется объект из списка
у меня есть список: private List&lt;T&gt; List = new List&lt;T&gt;(); где класс Т: public class T :...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru