- 클래스를 동적할당을 통해 객체화 할 경우 외부의 메모리 유출이 일어날 수도 있습니다.
- 동적할당으로 쓰여진 메모리 공간은 항상 정리해주어야 합니다.
- 소멸자도 Virtual선언이 안되있을 경우 포인터 타입에 따라 함수 호출이 일어납니다.
- 그러므로 모든 계층의 클래스의 소멸자를 호출할려면 기본클래스를
virtual 선언해주면 객체 타입에 따른 소멸자가 호출될 것입니다.예제) /*35.cpp*/
#include <iostream>
using std::endl;
using std::cout;
class Point {
int x_ptr;
int y_ptr;
char* pntName;
public:
Point(int _x = 0, int _y = 0, char* _name){
x_ptr = _x;
y_ptr = _y;
cout << "Point() OK!" << endl;
pntName = new char[strlen(_name)+1]; strcpy(pntName, _name);
}
~Point(){ cout << "~Point() OK!" << endl; delete pntName; }
void getPoint(){
cout << "X좌표 :" << x_ptr << endl;
cout << "Y좌표 :" << y_ptr << endl;
}
int getX() const {
return x_ptr;
}
int getY() const {
return y_ptr;
}
void draw() const{
cout << "점을 찍었습니다." << endl;
}
};
class Circle : public Point
{
char* cirName;
public:
Circle(int _x = 0, int _y = 0, char* _name) : Point(_x, _y, _name){
cout << "Circle() OK!" << endl;
cirName = new char[strlen(_name)+1]; strcpy(cirName, _name);
}
~Circle(){ cout << "~Circle() OK!" << endl; delete cirName; }
int getArea() const {
return getX() * getY();
}
void draw() const{
cout << "원을 그렸습니다." << endl;
}
};
class Cylinder : public Circle
{
int height;
char* cylName;
public:
Cylinder(int _x = 0, int _y = 0, int _height=0, char* _name) : Circle( _x , _y, _name){
height = _height;
cout << "Cylinder() OK!" << endl;
cylName = new char[strlen(_name)+1];
strcpy(cylName, _name);
}
~Cylinder(){
cout << "~Cylinder() OK!" << endl;
delete cylName;
}
int getVolume() const {
return getArea() * height;
}
void draw() const{
cout << "원기둥을 그렸습니다." << endl;
}
};
int main(){
Point * pnt1 = new Cylinder(3, 5, 8, "kim");
delete pnt1;
system("pause");
return 0;
}
- 실행결과
- 위 결과를 보면 나머지
Circle, Cylinder클래스에서 동적할당한 메모리에 대해서는 메모리 유출이 일어나므로 이를 해결해줘야 합니다
- 그러므로 Point의 소멸자를 Virtual선언 해주면 객체 타입에 따라 소멸자가 호출될 것입니다.
예제2) virtual선언된 소멸자
/*35-2.cpp*/
#include <iostream>
using std::endl;
using std::cout;
class Point
{
int x_ptr;
int y_ptr;
char* pntName;
public:
Point(int _x = 0, int _y = 0, char* _name){
x_ptr = _x;
y_ptr = _y;
cout << "Point() OK!" << endl;
pntName = new char[strlen(_name)+1]; strcpy(pntName, _name);
}
virtual ~Point(){ cout << "~Point() OK!" << endl; delete pntName; } void getPoint(){
cout << "X좌표 :" << x_ptr << endl;
cout << "Y좌표 :" << y_ptr << endl;
}
int getX() const {
return x_ptr;
}
int getY() const {
return y_ptr;
}
void draw() const{
cout << "점을 찍었습니다." << endl;
}
};
class Circle : public Point
{
char* cirName;
public:
Circle(int _x = 0, int _y = 0, char* _name) : Point(_x, _y, _name){
cout << "Circle() OK!" << endl;
cirName = new char[strlen(_name)+1]; strcpy(cirName, _name);
}
~Circle(){
cout << "~Circle() OK!" << endl;
delete cirName;
}
int getArea() const {
return getX() * getY();
}
void draw() const{
cout << "원을 그렸습니다." << endl;
}
};
class Cylinder : public Circle
{
int height;
char* cylName;
public:
Cylinder(int _x = 0, int _y = 0, int _height=0, char* _name) : Circle( _x , _y, _name){
height = _height;
cout << "Cylinder() OK!" << endl;
cylName = new char[strlen(_name)+1];
strcpy(cylName, _name);
}
~Cylinder(){
cout << "~Cylinder() OK!" << endl;
delete cylName;
}
int getVolume() const {
return getArea() * height;
}
void draw() const{
cout << "원기둥을 그렸습니다." << endl;
}
};
int main(){
Point * pnt1 = new Cylinder(3, 5, 8, "kim"); delete pnt1;
system("pause");
return 0;
}
- 실행결과
- 위 결과와 같이 포인터의 종류가 아닌
객체타입에 따라 소멸자가 호출됨을 알 수 있습니다.