Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: классы и STL  (Прочитано 10266 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
dorador
Гость
« : 02-12-2003 11:10 » 

прочел статью "STL и шаблоны" и попробовал применить STL в программе, которую сейчас пишу. и получилась некоторая вещь, которую не могу понять...
задал структуру и класс с указателем на список таких структур
Код:
typedef struct _Info {
ULONG Id;
ULONG Type;
} Info, *PInfo;

class CClassA
{
list <Info> *pMyList;
public:
CClassA();
~CClassA();
void setList();
};
Info i_01;

CClassA::CClassA()
{
pMyList = new list <Info>;
}

CClassA::~CClassA()
{
delete pMyList;
}

void CClassA::setList()
{
pMyList->push_back(i_01);
}
определил еще один класс, содержащий переменную-член и список элементов предыдущего класса
Код:
class CClassB
{
CClassA CLASS_A;
list <CClassA> *pMyClassAList;

public:
CClassB();
~CClassB();
void setList();
};
CClassB::CClassB()
{
pMyClassAList = new list <CClassA>;
CLASS_A.setList();
}

CClassB::~CClassB()
{
delete pMyClassAList;
}

void CClassB::setList()
{
pMyClassAList->push_back(CLASS_A);
}
вызываю так
Код:
	CClassB* pClassB = new CClassB;
pClassB->setList();
delete pClassB;
при выполнении оператора
   delete pClassB;
вываливается по недопустимому обращению к памяти
если убрать в деструкторе класса B оператор delete то не вываливается
похоже (по хождению в отладчике) что этот оператор delete вызывает лишнее обращение к деструктору класса A
но ведь по идее он должен быть
« Последнее редактирование: 23-11-2007 14:52 от Алексей1153++ » Записан
dorador
Гость
« Ответ #1 : 02-12-2003 11:34 » 

наверное это все от непонимания шаблонов :oops:
вот если я создам локально объект класса
и засуну его в список
Код:
if(...)
{
CClassA class_a;
m_pMyList->push_back(class_a);
}
в списке будет создана его копия ?
или так делать нельзя?
« Последнее редактирование: 23-11-2007 14:52 от Алексей1153++ » Записан
dorador
Гость
« Ответ #2 : 02-12-2003 14:12 » 

я кажется понял
объект класса А сначала удаляется, когда удаляется список, в который он входит, а затем еще раз пытается удалиться когда удаляется класс B.
сделал я вместо списка объектов класса А, список указателей и все теперь работает
Код:
class CClassB
{
CClassA* pCLASS_A;
list <CClassA*> *pMyClassAList;
public:
CClassB();
~CClassB();
void setList();
};
CClassB::CClassB()
{
pCLASS_A = new CClassA;
pMyClassAList = new list <CClassA*>;
pCLASS_A->setList();
}
CClassB::~CClassB()
{
delete pCLASS_A;
delete pMyClassAList;
}
void CClassB::setList()
{
pMyClassAList->push_back(pCLASS_A);
}
« Последнее редактирование: 23-11-2007 14:53 от Алексей1153++ » Записан
ysv_
Помогающий

ua
Offline Offline

« Ответ #3 : 02-12-2003 14:12 » 

Цитата

CClassA class_a;
   m_pMyList->push_back(class_a);

После выполнения этого кода в списке будет копия. Именно поэтому
Цитата

при выполнении оператора
delete pClassB;
вываливается по недопустимому обращению к памяти

так как у тебя нет конструктора копирования для CClassA, а к-тор по умолчанию копирует указатель *pMyList, для которого и вызывается delete дважды.
Кстати, а зачем усложнять себе жизнь динамическим созданием спсиков. Может можно обойтись и без этого?
Записан
dorador
Гость
« Ответ #4 : 02-12-2003 14:20 » 

ysv_,
Цитата

Кстати, а зачем усложнять себе жизнь динамическим созданием спсиков. Может можно обойтись и без этого?

что ты имеешь ввиду под динамическим созданием списков?
применение    list <CClassA> *pMyClassAList;
вместо    list <CClassA> MyClassAList;
если это, то я память пытался экономить, правда теперь сомневаюсь, что хоть что-то сэкономил :?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 02-12-2003 14:41 » new

dorador,  Может лучше такой вариант  -   list <CClassA*> MyClassAList; ?

Те у тебя стековый объект, в котором хранится список указателей. Создавать копии в списках можно, но зачем? Расход памяти и тд.  А так у тебя есть указатель, а объект лежит себе потихонечку никого не трогает. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ysv_
Помогающий

ua
Offline Offline

« Ответ #6 : 02-12-2003 14:48 » 

Цитата

что ты имеешь ввиду под динамическим созданием списков?
применение list <CClassA> *pMyClassAList;
вместо list <CClassA> MyClassAList;

Да. (с последующив вызовом new)
Цитата

если это, то я память пытался экономить, правда теперь сомневаюсь, что хоть что-то сэкономил

А смысл - сэкономить несколько байт? Держать в списке указатели - это я понимаю. А сами списки: разве что будеш создавать их тысячами.
А вообще, если в классе используются указатели, то следуют следующему правилу (есть даже абревиатура, но я ее не помню): обязательно объявить деструктор, конструктор копии и оператор присваивания, с помощью которых гарантируется одноразовый и только одноразовый вызов деструктора. Иначе хлопот не оберешся.
Записан
dorador
Гость
« Ответ #7 : 02-12-2003 14:55 » 

Джон, я тоже теперь к этому склоняюсь.
ysv_,  хорошее правило буду стараться ему следовать
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #8 : 05-12-2003 12:11 » 

если в списке хранить указатели, ну например так
typedef std::list<Object *> List;

List myList;

а потом напихать в него объекты, на пример так

Object * obj1 = new Object;
Object * obj2 = new Object;

myList.push_back(obj1);
myList.push_back(obj2);

то при разрушении списка (при выходе из области видимости) то произойдет утечка паняти..... потому как деструкторы у объектов не вызываются!!!! их нужно для каждого объекта вызывать руками!!!) ну например так

List::iterator iter = myList.begin();
for (; iter != myList.end() ; iter++)
    delete (*iter);

 Но зато при хранении в списке указателей на объекты, то в списке можно хранить как объекты типа Object, так и производные от Object объекты, а если в списке храняться объекты типа такого std::list<Object> , прои попытке поместить в список объект поизводный от Object произойдет обрезание!!!! Отлично  Отлично  Отлично (и это не шутка)

очень советую книгу Effective STL Майерса
« Последнее редактирование: 23-11-2007 14:55 от Алексей1153++ » Записан

С уважением Lapulya
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines