Advanced C++

[C++ 클래스] 순수 가상 소멸자

로파이 2021. 2. 18. 12:18

순수 가상 소멸자

 

순수 가상 함수를 포함하는 추상 클래스로 설계하고 싶을 때 사용한다.

일반적인 함수를 순수 가상 함수로 정의하지 않고 소멸자를 순수 가상 소멸자로 정의해서 추상 클래스로 정의한다.

 

Behavior라는 클래스는 Attack과 Defense 행동을 추상화한 클래스인데, 기본적으로 doAction()의 내용을 사용자가 정의해서 상속받은 클래스가 이 함수를 재사용하는 것을 생각한다.

class Behavior
{
private:
	string type;
    float duration;
public:
	Bahavior(string _type, float _duration)
    	: 
        type(_type),
        duration(_duration)
        {}
	virtual ~Behavior(){};
	virtual void doAction()
    {
    	cout << "My action" << type << endl;
    }
    
};

class Attack : public Behavior
{
private:
	int force;
public:
	Attack(string t, float d, int f) : Behavior(t,d), force(f) {}
    void doAction(Object* obj)
    {
    	Behavior::doAction();
        obj->GetDamage(force);
    }
};

class Defense : public Behavior
{
private:
	int defense;
public:
	Attack(string t, float d, int f) : Behavior(t,d), defense(f) {}
    void doAction(Object* obj)
    {
    	Behavior::doAction();
        obj->ApplyDefense(defense);
    }
};

Behavior 클래스는 추상화하지 않았기 때문에 다음과 같이 인스턴스를 생성할 수 있는데, 이는 설계자가 바라는 것이 아니므로 구성 함수 중 소멸자를 순수 가상 함수화 하여 인스턴스화 할 수 없게한다.

Behavior* pBh = Behavior("Unknown", 1.0f); // 의도하지 않은 인스턴스화
Behavior* pBh = Attack("MyAttack", 1.0f, 10);
Behavior* pBh = Defense("MyDefense", 1.0f, 5);

 

순수 가상 소멸자의 정의

virtual ~Behavior() = 0;

 

순수 가상 함수 여부와 상관 없이 소멸자는 인스턴스 소멸시 반드시 호출되어야하므로 구현 내용이 있어야한다.

다른 함수를 순수 가상 함수로 만들지 않고 클래스를 추상화하고 싶을 때 사용하는 방법이다.

class Component
{
private:
	vector<Object*> m_ItemList;
public:
	Component();
	~Component() = 0;
	virtual void Add(Object*);
	virtual Object* GetObject(string name);
};

Component::~Component()
{
	for(auto it = m_ItemList.begin(); it != m_ItemList.end(); it++)
    {
    	delete (*it);  // delete Object*
        *it = nullptr;  // Object* something = nullptr; 
    }
    m_ItemList.clear();
}