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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 5.00
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
#1

в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! - C++

26.06.2011, 22:40. Просмотров 2583. Ответов 55
Метки нет (Все метки)

Собсно


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Это типа служебного класса. (Внимание! В оригинальном коде он вложен в класс xx, но я этого не стал делать, дабы не усложнять код!)
class nemo_ {
};
 
//А это вот класс для конечного пользователя
class xx {
 public:
  nemo_& funktsia () {
  nemo_* ne= new nemo_ [1];
  return *ne;
 };
};
 
int main () {
 xx m;
 
 //Так, вот щас создастся объект класса nemo_; а нужен он для того, чтобы выполнился определённый код, который в нём скрывается
 m.funktsia ();
 //Тут пойдёт всякий разный код, и мне объект nemo_ больше не нужен
}
Вот как удалить объект класса nemo? Указателя не него в main нет, создать указатель в main НЕ ПРЕДЛАГАТЬ ибо это что же получается, конечный пользователь будет пользоваться классом xx и потом ещё должен будет заботиться об удалении nemo_, о котором он знать ничего не знает? Это не наш метод, наш метод даже не знаю какой, по-моему придётся смириться с утечкой памяти, пусть после m.funktsia (); объект типа nemo_ существует до конца проги. Так что ли?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2011, 22:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос в классе создаётся объект оператором new, как его удалить после использования в основной программе? delete в вызывающей функции не вариант! (C++):

Проверить на наличие вирусов после использования программы не вызывающей доверия - Удаление вирусов
Приветствую ! Так уж вышло, что сломал я неведомо как планировщик заданий и ничем не смог его воскресить, кроме программы, которая ну...

Используя условия вариантов записать все вычисления , проводимые ранее в основной программе , в виде процедуры. В основной программе предусмотреть т - Delphi
Используя условия вариантов записать все вычисления , проводимые ранее в основной программе , в виде процедуры. В основной программе...

Как создать объект оператором new, если имеется только тип указателя на объект, переданный через шаблон? - C++ Builder
Есть шаблон. Точно известно, что его параметр Т это указатель. Как с помощью new создать переменную типа *T ? Код приведенный ниже дает...

Что будет с указателем после использования операции delete? - C++
Имеется код: #include <iostream> using namespace std; int main() { int *wtf_ptr; wtf_ptr=new int(8);

Как сделать невидимым консольное окно в программе, вызывающей диалог? - C++ WinAPI
Простая тестовая программа#include <Windows.h> int main(int argc, char* argv) { MessageBox(NULL, "Окно", "Заголовок окна",...

Как удалить объект, по его Handle - Delphi WinAPI
Как, зная Хендл объекта чужого приложения, удалить его?

55
grizlik78
Эксперт С++
1967 / 1460 / 120
Регистрация: 29.05.2011
Сообщений: 3,019
27.06.2011, 00:20 #16
Цитата Сообщение от kravam Посмотреть сообщение
Так, там по-моему в сообщении N 18 и 20 я чётко расписал почему мне нужен КК и почему он ВООБЩЕ нужен.
Ситуации описанные и там и здесь называются просто: ошибки проектирования. Если тебя это устраивает, что ж, дело твоё. Правда тогда непонятно к чему эти вопросы
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
27.06.2011, 00:26  [ТС] #17
Да и бессмысленно включать оптимизацию и не вызывать тем самым конструктор копирования.

Ничё не выигрываю. Так он создастся с помощью new чёрт знает где, а этак- в вызывающей функции в стеке, который как бы ей принадлежит (без использования КК- твой вариант)

Но объект всё равно будет, вот в чём фишка.
А надо чтобы по использованию удалить. А никак. Вызвать деструктор- да, выполнится код, определённый в дестукторе. А объект создан в стеке, который принадлежит вызывающей функции, эта память системе не вернётся.

Так что невызов КК ничё не даст. Ты извини уж. Надо удалить именно созданый с помощью new, но нэто ни в какую, я уже понял

Добавлено через 3 минуты
Цитата Сообщение от grizlik78 Посмотреть сообщение
Ситуации описанные и там и здесь называются просто: ошибки проектирования.
прерогативу разбираться в названиях вещей я оставляю тем, кто не разбирается в самих вещах.
0
grizlik78
Эксперт С++
1967 / 1460 / 120
Регистрация: 29.05.2011
Сообщений: 3,019
27.06.2011, 00:29 #18
Цитата Сообщение от kravam Посмотреть сообщение
Да и бессмысленно включать оптимизацию и не вызывать тем самым конструктор копирования.
Оптимизацию включают не только для этого, но глупо делать копии, когда этого можно избежать.
Цитата Сообщение от kravam Посмотреть сообщение
Но объект всё равно будет, вот в чём фишка.
А надо чтобы по использованию удалить. А никак. Вызвать деструктор- да, выполнится код, определённый в дестукторе. А объект создан в стеке, который принадлежит вызывающей функции, эта память системе не вернётся.
Сама функция его из стека и удалит сразу же после вызова деструктора. Тоже мне проблема.

Добавлено через 1 минуту
Цитата Сообщение от kravam Посмотреть сообщение
прерогативу разбираться в названиях вещей я оставляю тем, кто не разбирается в самих вещах.
А как ещё назвать код, в котором осознано допускается утечка памяти и работоспособность которого зависит от опций компиляции?
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
27.06.2011, 00:52  [ТС] #19
какого деструктора? я же тебе говорю, конечный пользователь ничего не знает о классе nemo_, ёлки-палки и следовательно не должно быть в коде вызова
C++
1
~nemo_();
Добавлено через 18 минут
Цитата Сообщение от grizlik78 Посмотреть сообщение
Сама функция его из стека и удалит сразу же после вызова деструктора. Тоже мне проблема.
В дизассемблер не лазил, одно знаю, есть последовательность:
Удаление объекта-> вызов деструктора
Но не наоборот.
0
grizlik78
Эксперт С++
1967 / 1460 / 120
Регистрация: 29.05.2011
Сообщений: 3,019
27.06.2011, 00:59 #20
Цитата Сообщение от kravam Посмотреть сообщение
какого деструктора? я же тебе говорю, конечный пользователь ничего не знает о классе nemo_, ёлки-палки и следовательно не должно быть в коде вызова
Для автоматический объект явно деструктор вызывать и так нельзя. Он вызовется сам. Вызовется потому, что объект (тот-самый прокси объект, который участвует только на промежуточном этапе) вышел из области видимости.

Цитата Сообщение от kravam Посмотреть сообщение
В дизассемблер не лазил, одно знаю, есть последовательность:
Удаление объекта-> вызов деструктора
Но не наоборот.
если речь не о вызове delete, то последовательность действий целиком на усмотрении компилятора.

Добавлено через 3 минуты
Я имею в виду именно освобождение памяти, о котором и зашла речь. Меня эта последовательность даже не интересует и я мог бы написать не после, а вместе с вызовом деструктора.
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
27.06.2011, 01:45  [ТС] #21
Цитата Сообщение от grizlik78 Посмотреть сообщение
Для автоматический объект явно деструктор вызывать и так нельзя. Он вызовется сам. Вызовется потому, что объект (тот-самый прокси объект, который участвует только на промежуточном этапе) вышел из области видимости.
Тогда всё ещё запутанее.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
using namespace std;
 
class A
{
public:
    A()           { cout << "I'm default ctor\n"; }
    ~A()          { cout << "I'm destructor\n"; }
};
 
A g () {
 A a;
 return a;
} 
 
int main() {
    g ();
    getchar();
    return 0;
}
Включаем оптимизацию, КК не вызывается. Но деструктор вызывается. Почему? Из зоны видимости он не вышел- из зоны видимости не g, но конечно же main, ибо как я уже дал понять, он создался сразу в main и следовательно он автоматичен именно для main. Да, так вот. Функция main не закончилась, а объект, определённый в ней умер.

Вот это путаница. И не по названию, а по сути. И если она появилась вследствие оптимизации, то грош последней цена. Вот, наверное, потому я и отключаю её.
0
grizlik78
Эксперт С++
1967 / 1460 / 120
Регистрация: 29.05.2011
Сообщений: 3,019
27.06.2011, 01:57 #22
Цитата Сообщение от kravam Посмотреть сообщение
Включаем оптимизацию, КК не вызывается. Но деструктор вызывается. Почему? Из зоны видимости он не вышел- из зоны видимости не g, но конечно же main, ибо как я уже дал понять, он создался сразу в main и следовательно он автоматичен именно для main.
В функции main нет никакого объекта, который бы существовал до конца работы программы.. Конструктор копирования в данном случае не вызывается потому, что копировать некуда. Временный же объект, который является результатом вызова этой функции (и в который проискодит копирование при отключённой оптимизации копирования) имеет областью видимости вовсе не main, а лишь ту точку, где его можно было бы использовать при желании, то есть в месте вызова функции. Вот там он сразу же и удаляется. Нет никакой путаницы. Отключать оптимизацию неразумно. Иначе лучше вообще забыть и про C++ и даже про C и программировать сразу на ассемблере.

Добавлено через 1 минуту
Цитата Сообщение от kravam Посмотреть сообщение
Да, так вот. Функция main не закончилась, а объект, определённый в ней умер.
Этот объект был определён не в функции main. И оттого, что он умер, никому хуже не стало. И не могло стать.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 04:38 #23
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
A g () {
 A a;
012015D7  lea         ecx,[ebp-14h] 
012015DA  call        A::A (120111Dh) 
012015DF  mov         dword ptr [ebp-4],1 
 return a;
012015E6  lea         eax,[ebp-14h] 
012015E9  push        eax  
012015EA  mov         ecx,dword ptr [ebp+8] 
012015ED  call        A::A (1201267h) 
012015F2  mov         ecx,dword ptr [ebp-0E0h] 
012015F8  or          ecx,1 
012015FB  mov         dword ptr [ebp-0E0h],ecx 
01201601  mov         byte ptr [ebp-4],0 
01201605  lea         ecx,[ebp-14h] 
01201608  call        A::~A (1201145h) 
0120160D  mov         eax,dword ptr [ebp+8] 
} 
...
0120163F  ret
012015DA вызывается конструктор автоматического объекта
012015ED вызывается конструктор копирования*
01201608 вызывается деструктор для автоматического объекта
теперь в стеке находится объект А и управление возращается в main

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main() {
    g ();
012017DE  lea         eax,[ebp-0C8h] 
012017E4  push        eax  
012017E5  call        g (12010FAh) 
012017EA  add         esp,4 
012017ED  lea         ecx,[ebp-0C8h] 
012017F3  call        A::~A (1201145h) 
    getchar();
012017F8  mov         esi,esp 
012017FA  call        dword ptr [__imp__getchar (120A3DCh)] 
01201800  cmp         esi,esp 
01201802  call        @ILT+415(__RTC_CheckEsp) (12011A4h) 
    return 0;
01201807  xor         eax,eax 
}
тут хитроумный мелкомягкий компилятор видимо заметил, что управление над тем объектом A утеряно и удалил его до выхода из области видимости, что впринципе логично. Видимо kravam про этот автоматический объект в main говорил?

* Я изменил программу, добавив явный конструктор копирования
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
27.06.2011, 06:29 #24
Цитата Сообщение от kravam Посмотреть сообщение
Вот, наверное, потому я и отключаю её.
Ну с чего ты взял, что в namespace main'a хоть что-то создавалось? Ты вызвал функцию, в ней создался объект, при выходе из функции он уничтожился. Компилятор понимает, что объект А после завершения функции не используется, поэтому не копирует его. А ты этого не понимаешь, поэтому отключаешь оптимизацию. Что я могу ещё сказать - молодец!
1
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
27.06.2011, 07:33 #25
В дебаг версии VS 2008 копирует, потом уничтожает а. В коде мейн уничтожает копию. В релиз версии он тупо выводит строки cout-ом, никаких объектов А, копий и деструкторов...

mingw дебаг версии действительно не копирует даже
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
27.06.2011, 16:26  [ТС] #26
Цитата Сообщение от Deviaphan Посмотреть сообщение
Ну с чего ты взял, что в namespace main'a хоть что-то создавалось? Ты вызвал функцию, в ней создался объект, при выходе из функции он уничтожился. Компилятор понимает, что объект А после завершения функции не используется, поэтому не копирует его. А ты этого не понимаешь, поэтому отключаешь оптимизацию. Что я могу ещё сказать - молодец!
Не путай меня и не лги. Я нигде не вопрошал- почему КК не вызывается, если объект не возвращается? Потому и не вызывается, что как ты сам сказал "после завершения функции не используется", это я и без тебя знаю.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
27.06.2011, 16:28 #27
Да ты чо? А это что?
Цитата Сообщение от kravam Посмотреть сообщение
Почему? Из зоны видимости он не вышел- из зоны видимости не g, но конечно же main, ибо как я уже дал понять, он создался сразу в main и следовательно он автоматичен именно для main. Да, так вот. Функция main не закончилась, а объект, определённый в ней умер.
И где я лгу?
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
27.06.2011, 16:45  [ТС] #28
Алё, а при чём тут КК? Я спрашивал, почему объект, автоматичный для main, умер, а функция не закончилась ещё pito211 сказал, что "управление над тем объектом A утеряно и удалил его до выхода из области видимости, что впринципе логично"

А где в этой цитате спрашивал, почем не вызывается КК... и так далее?

Добавлено через 11 минут
pito211,ну да, я это и имел ввиду.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
using namespace std;
 
class A
{
public:
    A()           { cout << "I'm default ctor\n"; }
    ~A()          { cout << "I'm destructor\n"; }
};
 
A g () {
 A a;
 return a;
} 
 
int main() {
    g ();
    getchar();
    return 0;
}
Жаль, очень жаль, что в книгах написано одно, а на практике друое.
0
voral
490 / 470 / 79
Регистрация: 16.03.2008
Сообщений: 2,219
27.06.2011, 16:54 #29
Как все странно.... Объект класса nemo_ должен удаляться объектом класса xx. Разве что за исключением каких то специализированных случаев когда объект класса xx - всего лишь генератор для объектов класса nemo_. Во втором случае позаботиться об удалении объекта должен тот кто его заказал. Ваш случай похож и в данной реализации вы обязаны освободить память в main (не хотите - переделывайте класс xx в соответствии с условием задачи)

Если же первый случай. В каком методе класса xx будет удаляться объект класса nemo_ неважно. (в т.ч и в деструкторе и в конструкторе). Но объект класса хх должен хранить указатель на объект класса nemo_

Если вас не устраивает такой подход, выберите язык программирования с автоматической сборкой мусора.

Добавлено через 6 минут
А кажеться дошло о чем вы. Я не совсем в тему ответил похоже
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
27.06.2011, 17:12  [ТС] #30
Цитата Сообщение от voral Посмотреть сообщение
Разве что за исключением каких то специализированных случаев когда объект класса xx - всего лишь генератор для объектов класса nemo_.
примерно так, nemo_ на самом деле вложен для в xx и я переопределяю [][]

Ну в общем вывод такой: передаёшь ссыль- позаботься о delete; да всё бы ничё, но её только в main и вызывать; но тут случай, что и не видно, что это ссыль:

matrix_ []
[]

Ладно, остаётся только передавать объект. Как уж я подумаю. Всем спасибо, извините, кого задел.
0
27.06.2011, 17:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.06.2011, 17:12
Привет! Вот еще темы с ответами:

Как использовать объект класса, созданого в определеном классе, в другом классе - C#
У меня такой вопрос,как использовать объект класса,созданого в определеном классе,в другом классе.У меня есть объект pl класса Player,это...

Подключение M-функции к основной программе - Matlab
Здравствуйте. У меня есть M-функция, которая находит сумму всех элементов одномерного массива, стоящих на нечетных местах: ...

Как освободить память (ресурс) после его использования - C#
private void installButton_MouseEnter(object sender, EventArgs e) { installButton.Image =...

После использования функции strtok, как обращаться к лексемам? - C (СИ)
После использования функции strtok, как мне обращаться к лексемам? Допустим разбил я предложение мама мыла раму на 3 слова, теперь...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

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