나는 OO 이론 중 가장 확실한 이해를 하지만 인간으로 심아이엔큐 저를 많이 가상 플레이어임 소멸자.
항상 무엇이든 얻을 수 있는 생각해봤죠 객체당 체인에서의 의 소멸자 불렀으매 사용할 수 있습니다.
언제 할 때 그 가상 대체 왜?
한 때 사용할 수 있는 가상 소멸자 지정값이 삭제하시겠습니까 인스턴스입니다 포인터입니다 통해 파생 클래스 (base class):
class Base
{
// some virtual methods
};
class Derived : public Base
{
~Derived()
{
// Do some important cleanup
}
};
Base *b = new Derived();
// use b
delete b; // Here's the problem!
>. [In 'b' 삭제하시겠습니까] 의 경우 정적임 유형 >. 개체 유형, 정적임 동적임 변경분이 삭제해야만 다르다. >. 기본 클래스 객체의 타입은 동적 타입 될 것이라 할 수 없다. >. 정적 타입 삭제 및 the 투명지에 불지옥으 또는 가상 소멸자 >. 비헤이비어는 undefined.
대부분의 콜센터 구축 소멸자 해결될 수 있다는 것을 의미합니다. (base class) 의 소멸자 디바이스처럼 non-씬 코드를 불렀으매 파생 클래스 중 하나가 될 수 없지만, 그 결과 자료 유출.
요약, 항상 할 기본 classes& # 39. # 39 건, 다형 때 'virtual' 소멸자 they& 조작할 수 있을 정도다.
기본 클래스의 인스턴스를 삭제하는 것을 막기 위해 스케쳐내 통해 기본 클래스 소멸자 보호 및 비가 상 포인터입니다 할 수 있습니다. 이렇게 하면, 컴파일러, 삭제 '를' t let won& # 39 전화하시기 기본 클래스의 포인터입니다.
소멸자 비르투아르티 및 가상 (base class) 에 대한 추가 정보를 얻을 수 있는 (영문) 의 허브 서터.
그러나 가상 구성자를 수 없는 가상 소멸자 가능하다. Let us 것이다.
#include <iostream>
using namespace std;
class Base
{
public:
Base(){
cout << "Base Constructor Called\n";
}
~Base(){
cout << "Base Destructor called\n";
}
};
class Derived1: public Base
{
public:
Derived1(){
cout << "Derived constructor called\n";
}
~Derived1(){
cout << "Derived destructor called\n";
}
};
int main()
{
Base *b = new Derived1();
delete b;
}
위의 코드는 출력입니다 다음과 같습니다.
<! - 언어: > 랑 없음 -;
Base Constructor Called
Derived constructor called
Base Destructor called
하지만, 규칙에 따라 건설 공사 때 우리는 파생됨 객체에는 " 삭제하시겠습니까 b". 포인터 (기본 포인터입니다) 우리는 기본 소멸자 호출됨 지나지 않는 것으로 나타났다. 하지만 이 일어나지 않아야 합니다. 해당 할 수 있도록 해야 할 기본 소멸자 가상. 그럼 지금부터 어떤 조치를 취했는지 경우는 다음과 같습니다.
#include <iostream>
using namespace std;
class Base
{
public:
Base(){
cout << "Base Constructor Called\n";
}
virtual ~Base(){
cout << "Base Destructor called\n";
}
};
class Derived1: public Base
{
public:
Derived1(){
cout << "Derived constructor called\n";
}
~Derived1(){
cout << "Derived destructor called\n";
}
};
int main()
{
Base *b = new Derived1();
delete b;
}
출력물에는 변경일 다음과 같이.
<! - 언어: > 랑 없음 -;
Base Constructor Called
Derived Constructor called
Derived destructor called
Base destructor called
그래서 파괴를 기본 포인터 () 에 있는 는 할당일까요 파생됨 객체에는!) 문제가 된 후 첫 번째 규칙을 inet6.0 이리에 파생됨 기본. 반면 같은 가상 구성자를 없다.
다형 너희가운데 가상 의 소멸자 기반 클래스. # 39 이것은 항목설명프로세서 7 인 스콧 Meyers&. [Effective C++] [1]. 마이어스 댁이라면 않은 경우 클래스에는 모든 에 요약하십시오 가상 함수, 가상 소멸자 있어야 합니다 사용할 수 있으며, 클래스 기반 클래스, 방관하겠나 다형 않을 수 없습니다 너희가운데 가상 소멸자 한다.
[1]: http://www.amazon.com/effective-specific-addison-wesley-professional-computing/dp/ 0201924889
또한 기본 클래스의 삭제에서 점을 유념하십시오 포인터입니다 가상 소멸자 정의되지 않은 행동을 없을 때 발생합니다. 불과 얼마 생각하신거야 배웠다.
https://stackoverflow.com/questions/408196/how-should-overriding-delete-in-c-behave
struct Base {
virtual void f() {}
virtual ~Base() {}
};
struct Derived : Base {
void f() override {}
~Derived() override {}
};
Base* base = new Derived;
base->f(); // calls Derived::f
base->~Base(); // calls Derived::~Derived
가상 소멸자 전화 서비스는 다른 가상 함수 호출 다르지 않다.
F () 는 ',' 콜센터 '에 대한 base-> 디스패치되도록 파생됨 f ()', 그리고 it& # 39 에 대해 동일한 기본 () 는 함수, 즉 ',' base-> 재정의을 파생됨: ~ ~ '-' 을 파생됨 () 이라고 합니다.
예를 들어 ',' 기본 삭제하시겠습니까 간접적으로 소멸자 호출되는 동일한 때 발생합니다. '콜' 이 될 수 있는 기본 () ',' 명령문이 삭제하시겠습니까 base-> 파견 파생됨 파생됨: ~ ~ ' ()'.
않으려면 삭제하시겠습니까 객체에는 포인터입니다 - 그럼 그 베이스 클래스를 통해 가상 소멸자 필요가 없습니다. 그냥 ',' t be 할 수 있도록 # 39 라는 금지되었는지 won& 실수로:
// library.hpp
struct Base {
virtual void f() = 0;
protected:
~Base() = default;
};
void CallsF(Base& base);
// CallsF is not going to own "base" (i.e. call "delete &base;").
// It will only call Base::f() so it doesn't need to access Base::~Base.
//-------------------
// application.cpp
struct Derived : Base {
void f() override { ... }
};
int main() {
Derived derived;
CallsF(derived);
// No need for virtual destructor here as well.
}
간단하게 할 수 없다. 한 때 자폭 리소스를 가상 소멸자 () 는 기본 클래스의 객체를 가리키는 포인터를 이벤트수정적절한 오더할 삭제하시겠습니까 파생 클래스.
#include<iostream>
using namespace std;
class B{
public:
B(){
cout<<"B()\n";
}
virtual ~B(){
cout<<"~B()\n";
}
};
class D: public B{
public:
D(){
cout<<"D()\n";
}
~D(){
cout<<"~D()\n";
}
};
int main(){
B *b = new D();
delete b;
return 0;
}
OUTPUT:
B()
D()
~D()
~B()
==============
If you don't give ~B() as virtual. then output would be
B()
D()
~B()
where destruction of ~D() is not done which leads to leak
가상 찾을 때 필요한 것은 서로 다른 소멸자 따라야 하는 동안 주문하십시오 소멸자 운영까지도 이벤트수정적절한 개체가 삭제되는 베이스 클래스를 통해 포인터입니다. 예를 들면 다음과 같습니다.
Base *myObj = new Derived();
// Some code which is using myObj object
myObj->fun();
//Now delete the object
delete myObj ;
파생 클래스 소멸자 가상 플레이어임 어졌다면 객체에는 주문하십시오 데스트르쿠테드 수 있는 경우 (우선 파생됨 객체는 base). 가상 전용 기본 클래스 객체는 삭제할 수 없는 경우 다음 소멸자 파생 클래스 (base class) 는 기본 * myObj" 포인터입니다 때문에 ";). 따라서 메모리 누수가 파생됨 객체에는 위한 것입니다.
가상 소멸자 또는 가상 소멸자 지정하십시오. 사용 방법
A 클래스 (class 의 소멸자 기능이 있는 같은 이름의 앞 객체에는 클래스에 할당된 메모리 재할당합니다 ~ 앞으로 계속될 것 "이라고 말했다. 왜 우리가 필요로 하는 가상 소멸자
아래 샘플링합니다 일부 가상 기능
이 밖에도 샘플링합니다 편지를 변환할 수 있는 방법을 상위 또는 하위
#include "stdafx.h"
#include<iostream>
using namespace std;
// program to convert the lower to upper orlower
class convertch
{
public:
//void convertch(){};
virtual char* convertChar() = 0;
~convertch(){};
};
class MakeLower :public convertch
{
public:
MakeLower(char *passLetter)
{
tolower = true;
Letter = new char[30];
strcpy(Letter, passLetter);
}
virtual ~MakeLower()
{
cout<< "called ~MakeLower()"<<"\n";
delete[] Letter;
}
char* convertChar()
{
size_t len = strlen(Letter);
for(int i= 0;i<len;i++)
Letter[i] = Letter[i] + 32;
return Letter;
}
private:
char *Letter;
bool tolower;
};
class MakeUpper : public convertch
{
public:
MakeUpper(char *passLetter)
{
Letter = new char[30];
toupper = true;
strcpy(Letter, passLetter);
}
char* convertChar()
{
size_t len = strlen(Letter);
for(int i= 0;i<len;i++)
Letter[i] = Letter[i] - 32;
return Letter;
}
virtual ~MakeUpper()
{
cout<< "called ~MakeUpper()"<<"\n";
delete Letter;
}
private:
char *Letter;
bool toupper;
};
int _tmain(int argc, _TCHAR* argv[])
{
convertch *makeupper = new MakeUpper("hai");
cout<< "Eneterd : hai = " <<makeupper->convertChar()<<" ";
delete makeupper;
convertch *makelower = new MakeLower("HAI");;
cout<<"Eneterd : HAI = " <<makelower->convertChar()<<" ";
delete makelower;
return 0;
}
위에서 샘플링합니다 마쿠퍼 및 마이크로베르 클래스용 요구되지 않는 소멸자 모두 사용할 수 있음을 알 수 있습니다.
다음 샘플링합니다 볼 수 있는 가상 소멸자
#include "stdafx.h"
#include<iostream>
using namespace std;
// program to convert the lower to upper orlower
class convertch
{
public:
//void convertch(){};
virtual char* convertChar() = 0;
virtual ~convertch(){}; // defined the virtual destructor
};
class MakeLower :public convertch
{
public:
MakeLower(char *passLetter)
{
tolower = true;
Letter = new char[30];
strcpy(Letter, passLetter);
}
virtual ~MakeLower()
{
cout<< "called ~MakeLower()"<<"\n";
delete[] Letter;
}
char* convertChar()
{
size_t len = strlen(Letter);
for(int i= 0;i<len;i++)
{
Letter[i] = Letter[i] + 32;
}
return Letter;
}
private:
char *Letter;
bool tolower;
};
class MakeUpper : public convertch
{
public:
MakeUpper(char *passLetter)
{
Letter = new char[30];
toupper = true;
strcpy(Letter, passLetter);
}
char* convertChar()
{
size_t len = strlen(Letter);
for(int i= 0;i<len;i++)
{
Letter[i] = Letter[i] - 32;
}
return Letter;
}
virtual ~MakeUpper()
{
cout<< "called ~MakeUpper()"<<"\n";
delete Letter;
}
private:
char *Letter;
bool toupper;
};
int _tmain(int argc, _TCHAR* argv[])
{
convertch *makeupper = new MakeUpper("hai");
cout<< "Eneterd : hai = " <<makeupper->convertChar()<<" \n";
delete makeupper;
convertch *makelower = new MakeLower("HAI");;
cout<<"Eneterd : HAI = " <<makelower->convertChar()<<"\n ";
delete makelower;
return 0;
}
수업 시간 소멸자 실행하십시오 명시적으로 가상 소멸자 dial 가장 파생됨 객체의 선택해제합니다 적절한 방법으로 할 수 있다는 것입니다.
또는 dell. 링크
https://web.archive.org/web/20130822173509/http = 138 article_id ://www.programminggallery.com/article_details.php?
가상 소멸자 (base class, best practice" " 있다. - 메모리 누수 (hard to detect) 피하기 위해 항상 flfile. 합니다. 이를 사용하여, 당신의 모든 수업은 비링 불렀으매 상속 체인 의 소멸자 지시할 수 있습니다 (적절한 순서로). 사용할 수 있는 유일한 클래스 (base class) 에서 유일한 가상 소멸자 소멸자 자동으로 가상, 고쳐주렴 (# 39, & # 39 virtual& 재입력합니다 그러하매 필요가 없습니다. 클래스 상속 의 소멸자 선언).
'Shared_ptr 사용하는 경우' (전용 shared_ptr unique_ptr 아닌 경우), t # 39 don& 기본 클래스 소멸자 가상 있어야 한다.
"'
이름공간이 사용하여 표준용량.
기본 클래스 { 공개: 베이스 () { 코트 < <; 기본 생성자 Called\n" ";; } 베이스 () {/ / 필터링되지 가상 ~ 코트 < <; 기본 소멸자 called\n" ";; } };
클래스 파생됨: 공용 기본 { 공개: 파생됨 () { 코트 < <; " 파생됨 구성자를 called\n";; } ~ 파생됨 () { 코트 < <; 소멸자 called\n" 파생됨 ";; } };
int main () { shared_ptr< Base>; b (새 파생됨 ()); } "' 출력:
<! - 언어: > 랑 없음 -;
Base Constructor Called
Derived constructor called
Derived destructor called
Base Destructor called
&Quot 대해 논의하십시오 undefined" 것이 좋을 것 같아;; 비헤이비어를, 또는 적어도 " crash"; 정의되지 않은 행동을 통해 삭제에서 때 발생할 수 있는 가상 소멸자 또는 프터블 없이 기본 클래스 (/ 구조체입니다) 보다 정확하게 없습니다. 아래 코드는 목록*.직렬 몇 가지 간단한 구조체 (약간만이라도 flashcopy 같은 클래스에 대한).
#include <iostream>
using namespace std;
struct a
{
~a() {}
unsigned long long i;
};
struct b : a
{
~b() {}
unsigned long long j;
};
struct c : b
{
~c() {}
virtual void m3() {}
unsigned long long k;
};
struct d : c
{
~d() {}
virtual void m4() {}
unsigned long long l;
};
int main()
{
cout << "sizeof(a): " << sizeof(a) << endl;
cout << "sizeof(b): " << sizeof(b) << endl;
cout << "sizeof(c): " << sizeof(c) << endl;
cout << "sizeof(d): " << sizeof(d) << endl;
// No issue.
a* a1 = new a();
cout << "a1: " << a1 << endl;
delete a1;
// No issue.
b* b1 = new b();
cout << "b1: " << b1 << endl;
cout << "(a*) b1: " << (a*) b1 << endl;
delete b1;
// No issue.
c* c1 = new c();
cout << "c1: " << c1 << endl;
cout << "(b*) c1: " << (b*) c1 << endl;
cout << "(a*) c1: " << (a*) c1 << endl;
delete c1;
// No issue.
d* d1 = new d();
cout << "d1: " << d1 << endl;
cout << "(c*) d1: " << (c*) d1 << endl;
cout << "(b*) d1: " << (b*) d1 << endl;
cout << "(a*) d1: " << (a*) d1 << endl;
delete d1;
// Doesn't crash, but may not produce the results you want.
c1 = (c*) new d();
delete c1;
// Crashes due to passing an invalid address to the method which
// frees the memory.
d1 = new d();
b1 = (b*) d1;
cout << "d1: " << d1 << endl;
cout << "b1: " << b1 << endl;
delete b1;
/*
// This is similar to what's happening above in the "crash" case.
char* buf = new char[32];
cout << "buf: " << (void*) buf << endl;
buf += 8;
cout << "buf after adding 8: " << (void*) buf << endl;
delete buf;
*/
}
계획을 갖고 있는 경우 파생됨 삭제하시겠습니까 바타바레스 유지하는 데 필요한 기본 클래스 (base class 에서 인스턴스들도, 프터블 포인터가 있다. 그렇게 할 수 있는 가상 소멸자 추가하기에서는 한 것은 어쨌든 클린업합니다 리소스에는 제대로 할 수 있습니다.
내 생각에는 이 질문 내용 가상 방법 및 다형성, 특히 핵심 소멸자 않습니다. 다음은 명확한 예:
class A
{
public:
A() {}
virtual void foo()
{
cout << "This is A." << endl;
}
};
class B : public A
{
public:
B() {}
void foo()
{
cout << "This is B." << endl;
}
};
int main(int argc, char* argv[])
{
A *a = new B();
a->foo();
if(a != NULL)
delete a;
return 0;
}
출력됩니다.
This is B.
'Virtual' 없이 이 인쇄됩니다.
This is A.
그리고 지금 사용하는 경우 가상 소멸자 이해해야 합니다.