Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.09.2011, 23:58   #1
Trinock
Пользователь
 
Регистрация: 19.09.2011
Сообщений: 21
По умолчанию Удаление объекта производного класса оператором delete

Проблема в следующем. Есть базовый класс A от которого путем наследования создается класс B. Далее, я выделяю память под объект класса B инструкцией:

B *p = new B;

После этого заношу адрес этого объекта в список указателей на объекты класса A. Через некоторое время мне нужно освободить память из-под этого объекта. Я достаю из списка его адрес, присваиваю указателю на А:

A *pA;

дальше делаю преобразование типа:

B *deletingBObject = static_cast<B *>(pA).

И собственно удаляю объект:

delete deletingBObject;

Приложение выдает ошибку при выполнении последней инструкции. Что может быть не так? И можно ли подобным образом освобождать память из-под объекта производного класса?

Последний раз редактировалось Trinock; 20.09.2011 в 18:08. Причина: Исправлено с delete B на delete deletingBObject
Trinock вне форума Ответить с цитированием
Старый 20.09.2011, 00:35   #2
oblom
Пользователь
 
Аватар для oblom
 
Регистрация: 22.09.2007
Сообщений: 71
По умолчанию указатель

Я не совсем понял суть преобразования, вы удаляете объект или указатель на него, на сколько я знаю удаляют указатель освобождая зарезервированную под него область памяти...
"Пилите, Шура, пилите. Они золотые".....
oblom вне форума Ответить с цитированием
Старый 20.09.2011, 08:24   #3
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Цитата:
Сообщение от Trinock Посмотреть сообщение
Приложение выдает ошибку при выполнении последней инструкции. Что может быть не так? И можно ли подобным образом освобождать память из-под объекта производного класса?
Можно было бы и написать текст ошибки.
Если преобразование выполняется только с целью удаления объекта, то оно не надо. Заведите только правило на счет виртуальных деструкторов у базовых классов (оно в любом случае должно быть, даже если пользоваться не будете).
pu4koff вне форума Ответить с цитированием
Старый 20.09.2011, 10:00   #4
AJlekceu
Пользователь
 
Регистрация: 20.11.2010
Сообщений: 16
По умолчанию

delete B? B - это же класс, нет?
AJlekceu вне форума Ответить с цитированием
Старый 20.09.2011, 11:32   #5
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

Код:
class A
{
};

class B: public A
{
};

void Func()
{
    A *a = new B;
    // ...
    delete a;
}
Так правильно работает, без всяких кастов.
У вас ошибка в том, что вы, судя по всему, пытаетесь удалить не объект класса, а сам класс, т.е. тип.
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Старый 20.09.2011, 18:18   #6
Trinock
Пользователь
 
Регистрация: 19.09.2011
Сообщений: 21
По умолчанию

Цитата:
Сообщение от AJlekceu Посмотреть сообщение
delete B? B - это же класс, нет?
Исправил с delete B на delete deletingBObject, удаляю конечно по указателю, а не сам класс, тогда бы просто не скомпилировалось, а у меня ошибка возникает при выполнении программы когда удаляется объект. Прошу прощения за путаницу.

Цитата:
Сообщение от pu4koff
Можно было бы и написать текст ошибки.
Если преобразование выполняется только с целью удаления объекта, то оно не надо. Заведите только правило на счет виртуальных деструкторов у базовых классов (оно в любом случае должно быть, даже если пользоваться не будете).
Выскакивает исключение, связанное с обращением к недоступной памяти. Деструкторы виртуальные. То есть объект производного класса допускается удалять по указателю на базовый класс? Если деструкторы виртуальные, то будет вызван деструктор объекта базового класса? Видимо ошибка в другом.
Trinock вне форума Ответить с цитированием
Старый 20.09.2011, 18:43   #7
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от Trinock Посмотреть сообщение
Если деструкторы виртуальные, то будет вызван деструктор объекта базового класса?
Будут вызваны деструктор действительного типа объекта и деструкторы всех его базовых типов.
netrino вне форума Ответить с цитированием
Старый 21.09.2011, 16:37   #8
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

ваша проблема связана с использованием static_cast там, где нужно использовать dynamic_cast.

основное назначение static_cast - преобразование перечисляемых типов. а вас типичный случай даун-каста.
f.hump вне форума Ответить с цитированием
Старый 22.09.2011, 11:07   #9
artush1984
Форумчанин
 
Аватар для artush1984
 
Регистрация: 27.04.2009
Сообщений: 184
По умолчанию

Цитата:
Код:

class A
{
};

class B: public A
{
};

void Func()
{
A *a = new B;
// ...
delete a;
}

Так правильно работает, без всяких кастов.
У вас ошибка в том, что вы, судя по всему, пытаетесь удалить не объект класса, а сам класс, т.е. тип.
По моему не совсем так. Потому что в этом случаи вызывается только деструктр класса А значит память которая была взята для В останется и у нас будет утечка
Hа C я могy пpосто делать ошибки, на C++ я могy их наследовать!
artush1984 вне форума Ответить с цитированием
Старый 22.09.2011, 13:12   #10
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

Цитата:
Сообщение от artush1984 Посмотреть сообщение
По моему не совсем так. Потому что в этом случаи вызывается только деструктр класса А значит память которая была взята для В останется и у нас будет утечка
Нет, если деструкторы виртуальные (а они должны быть виртуальными в подобном примере)

Код:
#include <iostream>

class A
{
public:
  virtual ~A() {std::cout << "~A()" << std::endl;}
};

class B: public A
{
public:
  virtual ~B() {std::cout << "~B()" << std::endl;}
};

int main()
{
A *a = new B;
// ...
delete a;
}
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Java] Создание объекта внутри объекта этогоже класса. Svarogich Помощь студентам 2 01.08.2011 16:03
Потоковый вывод из производного класса Mike92 Общие вопросы C/C++ 11 08.05.2011 10:26
Ошибка при присвоении объекту производного класса объекта базового класса с исп. явного приведения типов Lanx Помощь студентам 0 06.04.2011 20:24
Как в базовом классе описать указатель на объект производного класса? MasterGH Общие вопросы C/C++ 3 16.11.2009 02:55
Если в классе объявить объект другого класса,будет ли видно переменные первого класса из объекта второго? TwiX Общие вопросы Delphi 3 15.11.2009 00:54