2016-10-14 7 views
-4

Быстрый вопрос,C++ Heap деструктор, когда типы данных неявно сохраняются

Я новичок в C++, и я трудно понять деструкторы.

Я объясню; скажем, у нас есть следующее;

int _a; 

a::a(int x) { 

    _a = x 
} 

тогда мы имеем

a* a1 = new a(8); 

Я понимаю, что данные А1 к создается на куче, и a1 указатель, где я не суметь это с деструктор;

a::~a() { 

    // confusion here 
} 

Поскольку _a не является указателем, так как он был создан неявно на куче благодаря новой (правильной), мы не можем удалить его, так что же нам делать?

ли

delete a1; 

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

+1

Не делайте того, чтобы вы не использовали символы подчеркивания для имен в вашем коде. Есть определенные случаи, когда они зарезервированы для реализации, поэтому лучше всего полностью избегать ситуации. – NathanOliver

+0

Что такое '_a'? И что заставляет вас верить, что это было создано на куче? – UnholySheep

+0

Также почему вы думаете, что вам нужно будет вызвать деструктор для 'int' (или любого другого« нормального »типа данных) и что сделает этот деструктор? – UnholySheep

ответ

1

Я понимаю, во что вы ездите, и ответ нет, деструкторы C++ не автоматически уничтожают данные, которые содержатся в вашем классе. К сожалению, ваш пример слишком ухищрен, чтобы хорошо осветить проблему. int - примитивный тип, поэтому его уничтожение является примитивным (кто-то может захотеть прокомментировать, что фактически происходит в int s деструктор). Рассмотрим следующий пример:

class A 
{ 
    public: 
    int x; 
    ~A() 
    { 
     std::out << "in A destructor" << std::endl; 
    } 
}; 

class B 
{ 
    public: 
    A* x; 

    B() 
    { 
     x = new A(); 
    } 

    ~B() 
    { 
     std::out << "in B destructor" << std::endl; 
     // does not automatically delete x 
    } 
}; 

auto x = new B(); 
delete x; 

В этом примере построения экземпляра B также построить экземпляр A, потому что вы явно новый его в конструкторе B. Однако, если вы явно не указали deletex в своем деструкторе для B, он не будет автоматически удален.

Небольшое изменение меня предыдущий пример, если бы B::x были типа A и не A*, в этом случае ответ является да, деструктор А будет называться.

Надеюсь, это поможет!

+0

'auto x = new B(); delete x; ' –

+0

my bad not use to stackoverflow Позвольте мне попробовать еще раз –

+0

так скажите, если бы у нас был' auto x = new A(); delete x; 'нам ничего не нужно в деструкторе A, поскольку он вызовет ints destructor? –

1

вызов деструктора для int автоматически?

Это было бы правдой, если бы объектом был тип класса. Для типов неклассов нет деструктора, даже неявно определенных. Следовательно, вопрос о вызове деструктора не возникает.

Если бы ваш код был что-то вроде:

struct Foo 
{ 
    Foo() {} 
    ~Foo() {} 
}; 

struct a 
{ 
    Foo f 
}; 

a* aptr = new a; 
delete aptr; 

Деструктор, Foo::~Foo(), будет называться для f.

1

Деструктор - это просто функция, которая вызывается автоматически, когда экземпляр выходит из области видимости.Это удобный способ выпустить динамически выделенную память.

Вам не нужно беспокоиться о выпуске переменных, которые были выделены в стеке (все, что было объявлено, а не новое -ed).

Например:

int localStackVar = 5; //no need to deallocate explicitly 
int* localPointer = &localStackVar // no need to deallocate explicitly 
int* heapValue = new int(); //Allocates to the heap so you need to call delete explicitly 

Первые два из примера выше в стеке, то первый один является ИНТ и второй является ИНТ указатель, который является просто способ сказать, что это переменная который содержит адрес памяти другой переменной. Обе из них будут освобождены автоматически, так как вы не назовете на них new.

Третья строка выделяет int в куче. Вы должны позвонить по номеру delete, когда он вам больше не нужен.

Если эти 3 переменные были частью класса, ваш конструктор и деструктор будет выглядеть следующим образом:

MyClass::MyClass() 
{ 
    heapValue = new int(); 
} 

MyClass::~MyClass() //destructor 
{ 
    delete heapValue; 
} 

void someFun() 
{ 
    MyClass instance; //constructor is called here 
    //do stuff 
    return; //destructor is called here 
} 

Таким образом, хотя MyClass instance является локальной переменной стека, когда объявленный в someFun , поскольку конструктор вызывается автоматически , heapVal указывается на ячейку памяти, находящуюся в куче, которая должна быть явно выпущена.

Если ваш деструктор не вызвал удаление на нем, память «утешилась», она не будет выпущена до тех пор, пока ваша программа не завершится.