2013-02-26 3 views
3

У меня есть класс внутри класса, вложенного классУдаляет ли указатель объекта основного класса удаление вложенных указателей классов?

class A { 
public: 
int a; 
int b; 
    class B { 
    int c; 
    int d; 
    } 
} 

В процессе, я выделяю указатель на объект класса В в куче.

B *bobj = new B(); 
    A *a; 
    auto_ptr<A> A1(new A()); 
    a = A1.release(); 

ли удаление а, удалить bobj, а ??

delete a; 

или мы должны явно удалить указатель подкласс?

Это код, который не был написан мной, я поставил журналы на все alloc и deallocs, и я вижу, что B *bobj = new B(), для этого нет удаления, а для объекта A ptr существует удаление. И все же утечки памяти нет. Вот почему я получил сомнение в том, что происходит в этом сценарии.

+1

«В процессе ..» какой процесс? Что означает «A * a»? – juanchopanza

+0

@nvoigt это даже не нарушение прав доступа, это ошибка компилятора. – juanchopanza

+0

Я боюсь, что все, что вы говорите, ошибочно: вы не выделяете указатель на кучу, а скорее * объект *. Указатель - это автоматическая переменная. И слово «подкласс», ужасное, как есть, действительно не означает, что вы думаете. Во всяком случае, у вас есть «вложенный класс». –

ответ

9

Я думаю, вы немного смущены здесь. Если у вас есть объект типа A, он не имеет внутри него объекта B. Он просто имеет два int s, a и b. Ваш класс B просто объявлен как вложенный класс внутри A - аналогично объявлению его в пространстве имен. Он должен называться A::B вне класса (и должен быть public для этого).

В примере кода, который вы указали, B *bobj = new B(); A *a;, вы даже не создаете объект A. Я полагаю, вы имели в виду это (предполагая, что вы делаете Bpublic):

A::B *bobj = new A::B(); 
A *a = new A(); 

Оба a и bobj являются отдельными объектами. Они не имеют ничего общего друг с другом. У вас должно быть delete оба из них.

Если вместо того, чтобы вы сделали это:

class B { 
    int c; 
    int d; 
}; 

class A { 
    int a; 
    B b; 
}; 

Теперь объект класса типа A имеет элемент называется b, который имеет тип B. Этот элемент b является частью любого объекта типа A. Так что если вы делаете A* a = new A();, вы получаете объект A с объектом B внутри него. Вы должны делать только delete a;.

Золотое правило: только delete у вас есть new ed.

+1

Но 'B' не может быть создан таким образом, если только этот экземпляр не находится внутри' A :: '. – juanchopanza

+1

@juanchopanza Спасибо, я пропустил это. –

+1

И 'B' является частным :-) – juanchopanza

2

Вкратце, C++ автоматически не удаляет указатели объектов (без специализированных указателей авто и т. Д.). Итак, явно удаляют их в вашей программе.

delete a; вызов деструктора класса A. Вы можете написать код для удаления объекта B внутри деструктора.

+0

«Итак, явно удалите их в своей программе». Да, но я бы предпочел подчеркнуть, что ** лучше использовать такие «авто-указатели и т. Д.», 'Unique_ptr' - отличный выбор для многих ситуаций. – leftaroundabout

+0

@ mark, @ leftaroundabout: можете ли вы дать мне больше информации о умных, автоматических указателях или ссылках на любой материал. – user862833

+1

вот одно приятное описание: http://stackoverflow.com/questions/6876751/differences-between-unique-ptr- and-shared-ptr – mark

3

, как вы написали код, class B вложенный тип в class A, но ни одного случая class B не содержится в class A, а это означает, что конкретизация - и, следовательно, разрушение - должна управляться отдельно. Так что да, вам нужно delete оба, если вы new оба.

3

Это зависит от того, что делает ваш деструктор. Если A содержит указатель типа B и в деструкторе A этот указатель отпущен - да. Если A не содержит указатель типа B и/или в указателе деструктора A на B не выпущен - вы должны отпустить его вручную.

+0

Спасибо. Я пытался удалить его в деструкторе, но объект был объявлен в области этой конкретной функции класса A, поэтому iam не смог удалить этот объект в деструкторе. – user862833