반응형
virtual 예시에서 사용한 코드에서 소멸자를 추가한 후, foodList의 메모리를 해제해보자.
각 class에 생성자를 추가하고 foodList[0]은 new FOOD로 수정하였다.
#include <stdio.h>
#include <iostream>
using namespace std;
class FOOD
{
private:
int price = 0;
public:
FOOD() { printf("FOOD created\n"); }
~FOOD() { printf("FOOD deleted\n"); }
virtual void printName() { cout << "FOOD Class" << endl; }
virtual void printPrice() { cout << this->price << endl; }
void printLine() { cout << "=================" << endl; }
};
class SNACK : public FOOD
{
private:
int price = 1000;
public:
SNACK() { printf("SNACK created\n"); }
~SNACK() { printf("SNACK deleted\n"); }
void printName() { cout << "SNACK Class" << endl; }
void printPrice() { cout << this->price << endl; }
};
class MILK : public FOOD
{
private:
int price = 500;
public:
MILK() { printf("MILK created\n"); }
~MILK() { printf("MILK deleted\n"); }
void printName() { cout << "MILK Class" << endl; }
void printPrice() { cout << this->price << endl; }
};
int main(void)
{
FOOD* foodList[3];
foodList[0] = new FOOD();
foodList[1] = new MILK();
foodList[2] = new SNACK();
printf("\n---- TEST START ----\n\n");
for (int i = 0; i < 3; i++)
{
foodList[i]->printName();
foodList[i]->printPrice();
foodList[i]->printLine();
putchar('\n');
}
for (int i = 0; i < 3; i++) delete foodList[i];
return 0;
}
FOOD를 상속받은 MILK와 SNACK은 FOOD 생성자가 호출된 후, MILK / SNACK 생성자가 호출되지만,
소멸자에서는 FOOD의 소멸자만 호출되고 있다.
Parent p = new Child() → 형변환이 이루어진 포인터 변수이기 때문에 원래 형태(부모)의 함수/소멸자만 호출된다.
이 코드에서는 큰 문제가 없지만, 만약 SNACK이나 MILK가 소멸되면서 메모리를 해제해야할 경우,
SNACK과 MILK의 소멸자가 호출되지 않기 때문에 메모리 누수 문제가 발생할 수 있다.
문제를 해결하는 방법은 소멸자도 virtual로 선언하는 것이다.
class FOOD
{
private:
int price = 0;
public:
FOOD() { printf("FOOD created\n"); }
virtual ~FOOD() { printf("FOOD deleted\n"); } /* 가상 소멸자 */
virtual void printName() { cout << "FOOD Class" << endl; }
virtual void printPrice() { cout << this->price << endl; }
void printLine() { cout << "=================" << endl; }
};
부모의 소멸자에 virtual로 선언하면, 자식의 소멸자가 먼저 호출된 후, 부모의 소멸자가 호출되어
정상적으로 메모리를 해제할 수 있게 된다.
반응형
'개발 > C, C++' 카테고리의 다른 글
C++ - 형변환 연산자 (casting operators) (0) | 2021.08.26 |
---|---|
C++ - virtual / override 키워드 (0) | 2021.08.25 |
C++ - explicit 키워드 (0) | 2021.08.22 |
C++ - virtual, type casting (0) | 2021.08.15 |
C++ - virtual 키워드 (0) | 2021.08.14 |
댓글