서브 클래스에 대한 포인터에서 delete가 기본 클래스 소멸자를 호출합니까?
나는이 class A
해당 필드 중 하나에 대한 힙 메모리 할당을 사용하는합니다. 클래스 A는 인스턴스화되어 다른 클래스 ( class B
.
클래스 B의 객체로 작업을 마치면 delete
소멸자를 호출한다고 가정합니다. 그러나 이것이 클래스 A의 소멸자를 호출합니까?
편집하다:
답변에서 나는 그것을 취합니다 (잘못된 경우 편집하십시오).
delete
B의 인스턴스 중 B :: ~ B ();- 어떤 전화
A::~A();
A::~A
delete
A 객체의 모든 힙 할당 멤버 변수를 명시 적으로 지정 해야 합니다.- 마지막으로 클래스 B의 인스턴스를 저장하는 메모리 블록은 힙으로 반환됩니다. 새로운 메모리가 사용될 때 , 먼저 힙에 메모리 블록을 할당 한 다음 생성자를 호출하여 초기화합니다. 객체가있는 블록은 힙으로 반환됩니다.
수명이 끝나면 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
new가 할당 한 포인터에서 delete를 호출하면 지정된 객체의 소멸자가 호출됩니다.
A * p = new A;
delete p; // A:~A() called for you on obkect pointed to by p
이름은 "소멸자"가 아니라 "소멸자"입니다.
각 클래스의 소멸자 내에서 new로 할당 된 다른 모든 멤버 변수를 삭제해야합니다.
편집 : 명확하게 :
당신이 가지고 있다고
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의 인스턴스는 해제되지 않은 A의 인스턴스를 할당하기 때문에 메모리가 누출됩니다 (이 경우 C에는 소멸자도 없음).
If you have a usual pointer (A*
) then the destructor will not be called (and memory for A
instance will not be freed either) unless you do delete
explicitly in B
's destructor. If you want automatic destruction look at smart pointers like auto_ptr
.
You should delete A yourself in the destructor of B.
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;
}
};
When you do:
B *pD = new D();
delete pD;
The destructor will be called only if your base class has the virtual keyword.
Then if you did not have a virtual destructor only ~B() would be called. But since you have a virtual destructor, first ~D() will be called, then ~B().
No members of B or D allocated on the heap will be deallocated unless you explicitly delete them. And deleting them will call their destructor as well.
I was wondering why my class' destructor was not called. The reason was that I had forgot to include definition of that class (#include "class.h"). I only had a declaration like "class A;" and the compiler was happy with it and let me call "delete".
No. the pointer will be deleted. You should call the delete on A explicit in the destructor of B.
The destructor for the object of class A will only be called if delete is called for that object. Make sure to delete that pointer in the destructor of class B.
For a little more information on what happens when delete is called on an object, see: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9
no it will not call destructor for class A, you should call it explicitly (like PoweRoy told), delete line 'delete ptr;' in example to compare ...
#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;
}
You have something like
class B
{
A * a;
}
B * b = new B;
b->a = new A;
If you then call delete b;
, nothing happens to a, and you have a memory leak. Trying to remember to delete b->a;
is not a good solution, but there are a couple of others.
B::~B() {delete a;}
This is a destructor for B that will delete a. (If a is 0, that delete does nothing. If a is not 0 but doesn't point to memory from new, you get heap corruption.)
auto_ptr<A> a;
...
b->a.reset(new A);
This way you don't have a as a pointer, but rather an auto_ptr<> (shared_ptr<> will do as well, or other smart pointers), and it is automatically deleted when b is.
Either of these ways works well, and I've used both.
'IT' 카테고리의 다른 글
하위 프로세스 Popen과 call의 차이점은 무엇입니까 (어떻게 사용할 수 있습니까)? (0) | 2020.06.02 |
---|---|
Enter를 누르지 않고 표준 입력에서 문자를 캡처합니다. (0) | 2020.06.02 |
다음 LINQ 문은 어떻게 작동합니까? (0) | 2020.06.02 |
명령 프롬프트-해당 배치 파일이 실행되도록 설정된 경로를 추가하는 방법은 무엇입니까? (0) | 2020.06.01 |
MySQL 데이터베이스 테이블의 최대 레코드 수 (0) | 2020.06.01 |