Действительно удаляет на указателе на вызов подкласса деструктор базового класса?

Я не уверен, как вы узнаете, что вас перенаправили, но давайте предположим, что это переменная redirected, если redirected истинно, div с кнопками будет скрыт, а остальные - видимыми. Если вы предоставите лучший вариант использования, я обновлю мой ответ.


const wrapper = document.getElementById('wrapper');
const willShow = document.getElementById('willShow');
const buttonsContainer = document.getElementById('buttons-container');

const redirected = true;
if(redirected) {
  buttonsContainer.style.display = 'none';
  willShow.style.display = 'block';
}

https://codepen.io/anon/pen/RdEgQj

161
задан einpoklum - reinstate Monica 16 April 2019 в 21:03
поделиться

10 ответов

Деструктор A будет работать, когда его время жизни будет закончено. Если Вы хотите, чтобы его память была освобождена и выполненный деструктор, необходимо удалить его, если бы он был выделен на "куче". Если это было выделено на стеке, это происходит автоматически (т.е. когда это выходит из объема; см. RAII). Если это будет член класса (не указатель, а полноправный член), то это произойдет, когда содержание объекта будет уничтожено.

class A
{
    char *someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { delete[] someHeapMemory; }
};

class B
{
    A* APtr;
public:
    B() : APtr(new A()) {}
    ~B() { delete APtr; }
};

class C
{
    A Amember;
public:
    C() : Amember() {}
    ~C() {} // A is freed / destructed automatically.
};

int main()
{
    B* BPtr = new B();
    delete BPtr; // Calls ~B() which calls ~A() 
    C *CPtr = new C();
    delete CPtr;
    B b;
    C c;
} // b and c are freed/destructed automatically

В вышеупомянутом примере, каждый удалять и удаляют [], необходим. И не удалите, необходим (или действительно способный использоваться), где я не использовал его.

auto_ptr, unique_ptr и shared_ptr и т.д.... являются большими для того, чтобы сделать это пожизненное управление намного легче:

class A
{
    shared_array<char> someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { } // someHeapMemory is delete[]d automatically
};

class B
{
    shared_ptr<A> APtr;
public:
    B() : APtr(new A()) {}
    ~B() {  } // APtr is deleted automatically
};

int main()
{
    shared_ptr<B> BPtr = new B();
} // BPtr is deleted automatically
180
ответ дан MatrixFrog 23 November 2019 в 21:27
поделиться

То, когда Вы звоните, удаляют на указателе, выделенном новым, деструктор объекта указал, назовут.

A * p = new A;

delete p;    // A:~A() called for you on obkect pointed to by p
30
ответ дан 23 November 2019 в 21:27
поделиться

Это называют "деструктором", не "deconstructor".

В деструкторе каждого класса необходимо удалить все другие членские переменные, которые были выделены с новым.

править: Разъясниться:

Скажите, что Вы имеете

struct A {}

class B {
    A *a;
public:
    B () : a (new A) {}
    ~B() { delete a; }
};

class C {
    A *a;
public:
    C () : a (new A) {}        
};

int main () {
    delete new B;
    delete new C;
}

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

Но экземпляры класса C пропустят память, потому что это выделяет экземпляр, который это не выпускает (в этом случае C, даже не имеет деструктора).

22
ответ дан Sebastian Mach 23 November 2019 в 21:27
поделиться

Если у Вас есть обычный указатель (A*) затем деструктор не назовут (и память для A экземпляр не будет освобожден ни один), если Вы не сделаете delete явно в Bдеструктор. Если Вы хотите автоматический взгляд разрушения на интеллектуальные указатели как auto_ptr.

5
ответ дан Unihedron 23 November 2019 в 21:27
поделиться

Необходимо удалить сами в деструкторе B.

4
ответ дан corné 23 November 2019 в 21:27
поделиться
class B
{
public:
    B()
    {
       p = new int[1024];  
    }
    virtual ~B()
    {
        cout<<"B destructor"<<endl;
        //p will not be deleted EVER unless you do it manually.
    }
    int *p;
};


class D : public B
{
public:
    virtual ~D()
    {
        cout<<"D destructor"<<endl;
    }
};

Когда Вы делаете:

B *pD = new D();
delete pD;

Деструктор назовут, только если Ваш базовый класс имеет виртуальное ключевое слово.

Затем, если бы у Вас не было виртуального деструктора только ~B (), то был бы назван. Но так как у Вас есть виртуальный деструктор, первый ~D () назовут, затем ~B ().

Никакие члены B или D, выделенного на "куче", не будут освобождены, если Вы явно не удалите их. И удаление их назовет их деструктор также.

3
ответ дан Brian R. Bondy 23 November 2019 в 21:27
поделиться

Нет. указатель будет удален. Необходимо назвать удаление на явном в деструкторе B.

0
ответ дан RvdK 23 November 2019 в 21:27
поделиться

нет это не назовет деструктор для класса A, необходимо звонить, это явно (как PoweRoy сказал), удалите строку, 'удаляют ptr'; в примере для сравнения...

  #include <iostream>

  class A
  {
     public:
        A(){};
        ~A();
  };

  A::~A()
  {
     std::cout << "Destructor of A" << std::endl;
  }

  class B
  {
     public:
        B(){ptr = new A();};
        ~B();
     private:
        A* ptr;
  };

  B::~B()
  {
     delete ptr;
     std::cout << "Destructor of B" << std::endl;
  }

  int main()
  {
     B* b = new B();
     delete b;
     return 0;
  }
0
ответ дан Darius Kucinskas 23 November 2019 в 21:27
поделиться

Деструктор для объекта класса A только назовут, если удалят, назван для того объекта. Удостоверьтесь, что удалили тот указатель в деструкторе класса B.

Для немного большей информации о то, что происходит, когда удаляют, называют на объекте, см.: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9

0
ответ дан Kris Kumler 23 November 2019 в 21:27
поделиться

У Вас есть что-то как

class B
{
   A * a;
}
B * b = new B;
b->a = new A;

Если Вы затем звоните delete b;, ничего не происходит с a, и у Вас есть утечка памяти. Попытка помнить к delete b->a; не хорошее решение, но существует несколько других.

B::~B() {delete a;}

Это - деструктор для B, который удалит a. (Если 0, которые удаляют, ничего не делает. Если не 0, но не указывает на память от нового, Вы получаете повреждение "кучи".)

auto_ptr<A> a;
...
b->a.reset(new A);

Таким образом, Вы не имеете как указатель, а скорее auto_ptr <> (shared_ptr <> сделает также, или другие интеллектуальные указатели), и он автоматически удален, когда b.

Любой из этих путей работает хорошо, и я использовал обоих.

0
ответ дан David Thornley 23 November 2019 в 21:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: