다음과 같은 코드가 있다.

#include <iostream>
using namespace std;

class Something {
public:
	Something() { cout << "2"; }
	~Something() { cout << "~2"; }
};

class Parent {
public:
	Parent() { cout << "1"; }
	~Parent() { cout << "~1"; }
};

class Child : public Parent {
public:
	Child() { cout << "3"; }
	~Child() { cout << "~3"; }

private:
	Something mDataMember;
};

 

 

이렇게 할 경우 정상적으로 소멸된다.

int main() {
	Child c;

	return 0;
}

정상

 

 

아래처럼 동적으로 생성한 파생 클래스 객체를 부모클래스 포인터로 가리키고 있을 경우 소멸 순서가 엉망이 된다.

int main() {
	Parent* ptr = new Child();
	delete ptr;

	return 0;
}

~2, ~3이 호출안됨.

 

Parent타입의 포인터로 delete하면 child의 소멸자가 이닌 Parent의 소멸자가 불러져서 Child의 소멸자와 Child의 데이터 멤버도 삭제가 안됩니다.

 

해결방법은 Parent의 소멸자를 virtual로 만들면 된다.

 

 

부모 클래스에서 virtual을 붙이면 파생 클래스에 자동으로 virtual이 적용되지만..

소멸자를 만들때마다 virtual 키워드를 가져다 붙이는 습관을 만들자.

#include <iostream>
using namespace std;

class Something {
public:
	Something() { cout << "2"; }
	virtual ~Something() { cout << "~2"; }
};

class Parent {
public:
	Parent() { cout << "1"; }
	virtual ~Parent() { cout << "~1"; }
};

class Child : public Parent {
public:
	Child() { cout << "3"; }
	virtual ~Child() { cout << "~3"; }

private:
	Something mDataMember;
};

int main() {
	Parent* ptr = new Child();
	delete ptr;

	return 0;
}

virtual 붙이니까 정상

 

+ Recent posts