2012-04-03 2 views
1

Могу ли я объявить новые переменные, например, один из другого класса, в c'tor? Предположим, у меня есть класс с именем списка и узла (вложен в классе List), то я хочу сделать:C'tor в классе C++

List::List(int num) 
{ 
Node Nod(num); //creating a new Node which is holding num 
List_Head=&Nod; //List_Head is a Node pointer variable of List class 
} 

После того, как я делаю это, я получаю следующее Runtime Ошибка:

Ошибка отладки!

Expression: _BLOCK_TYPE_IS_VALID (pHead-> nBlockUse)

Любая помощь?

+0

Это базовый C++, вы назначаете адрес локальной (то есть временной) переменной.Когда вы выходите из области c'tor, «Nod» удаляется, а также память, указанная «List_Head». – azf

ответ

3

Объем и время жизни Nod, которые вы создаете, ограничены конструктором List::List() Так как это локальный/автоматический объект.

После того, как конструктор возвращает Nod не существует и все указует на него (List_Head) является оборванным указателем, deferencing это приведет к непредсказуемому поведению и, скорее всего аварии.

Вы должны создать Node в динамической памяти (куче), вызвав new, если вы хотите отсылать его за пределы тела конструктора.

List_Head = new Node(num); 

в идеале, вы должны использовать что-нибудь вроде смарта-указателя вместо сырого указателя на List_Head, так что вам не придется вручную управления памятью. Если вам не нужно звонить:

delete List_Head; 

после того, как вы закончите с использованием, чтобы избежать утечки памяти.

+0

Но если я создаю узел в динамической памяти, это всего лишь указатель. Узел * nod = new Node; Я хочу создать не указатель, а переменную узла и вставить в него NUM. Как мне это сделать? – Jjang

+0

@ user1309152: да, что не так с этим? Пока у вас есть действительный указатель, указывающий на выделенную память, все безопасно. –

0

Вы не можете сделать это так. Nod выходит за пределы области действия в конце конструктора (последний }), что означает, что его память недействительна, а это означает, что List_Head указывает на недопустимую память.

Если вы хотите сохранить память вокруг, вы должны использовать new, как

List_Head = new Node(num); 

Просто убедитесь, что вы deletenew! Но вы должны быть осторожны с этим! Память может протекать, если вы ее не удаляете, или ее можно удалить дважды, если вы не справитесь с ней правильно. В частности, вам необходимо также реализовать деструктор, конструктор копирования и оператор присваивания, чтобы правильно обрабатывать выделенную память.

В качестве альтернативы вы можете использовать интеллектуальные указатели (например, std::shared_ptr, если вы используете C++ 11), чтобы обрабатывать удаления для вас, чтобы вы не утечка памяти или двойной памяти удаления. Возможно, вам придется определить свой конструктор копий и оператор присваивания, хотя, в зависимости от того, как вы хотите, чтобы ваш класс действовал (потому что без пользовательских версий вы получите shallow copy объекта, а не deep copy, что может и не быть вы хотите).

+0

Спасибо, давайте предположим, что у меня не было List_Head. Как я могу это сделать? – Jjang

+0

Ты ведь застрял. Вы не можете динамически добавлять членов к таким классам. – Cornstalks

Смежные вопросы