상세 컨텐츠

본문 제목

Virtual 소멸자

C++/다형성

by nowpassion 2008. 5. 5. 14:27

본문

- 클래스를 동적할당을 통해 객체화 할 경우 외부의 메모리 유출이 일어날 수도 있습니다.

- 동적할당으로 쓰여진 메모리 공간은 항상 정리해주어야 합니다.

- 소멸자도 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;
}

- 실행결과
사용자 삽입 이미지











- 위 결과와 같이 포인터의 종류가 아닌 객체타입에 따라 소멸자가 호출됨을 알 수 있습니다.

'C++ > 다형성' 카테고리의 다른 글

연산자 오버로딩  (0) 2008.05.05
가상테이블(Virtual Table)  (0) 2008.05.05
순수가상함수와 추상클래스  (0) 2008.05.05

관련글 더보기