부품간의 조립, 객체간의 연결이 다형성을 통해서 어떻게 보다 효율적으로 이루어질 수 있는지 알아보자.


원은 도형이며, 원과 도형은 'is-a' 관계를 가지고 있다는 뜻이다.



전체소스보기



위 소스는 아래와 같은 결과를 출력한다.


멤버 변수의 경우에는 부모 클래스로부터 상속 받은 것을 그대로 사용할 수 밖에 없지만 멤버 함수의 경우에는 부모 클래스에서 구현한 것이 맘에 들지 않는다면 자기에게 맞도록 새롭게 정의할 수 있다.


보관한 객체를 사용하기 그리고 문제점

실제로 수십가지의 도형이 존재할 수 있기 때문에 수십 가지의 도형별로 배열을 만들고 관리하는 것은 너무 귀찮고 비효율적이다.

대신 이 모든 클래스들이 Shape 클래스의 자식 클래스라는 점을 사용해서 하나의 배열에 모든 객체를 보관할 수 있다.

int main()
{
    // 도형들을 담을 배열을 준비
    Shape* shapes[5] = {NULL};

    // 각 타입의 객체를 생성해서 배열에 보관한다
    Shapes[0] = new Circle(100, 100, 50);
    Shapes[1] = new Rectangle(300, 300, 100, 100);
    Shapes[2] = new Rectangle(200, 100, 50, 150);
    Shapes[3] = new Circle(100, 300, 150);
    Shapes[4] = new Rectangle(200, 200, 200, 200);

    // 배열에 보관된 모든 객체를 그린다
    for(int i = 0; i < 5; ++i)
    {
        shapes[i] -> Draw();
    }

    // 배열에 보관된 모든 객체를 소멸
    for(i = 0; i < 5; ++i)
    {
        delete shapes[i];
        shapes[i] = NULL;
    }

    return 0;
}


위의 소스는 아래와 같은 모양으로 메모리를 구성한다.

동적으로 생성한 객체가 5개 있고 배열에 그 객체들이 보관되었다. 여러가지 타입의 객체를 하나의 배열에 넣어 두었기 때문에 손쉽게 사용할 수 있었다.


하지만 아래의 결과 출력처럼 Shape::Draw() 함수를 출력했다는 뜻이다.


가상함수를 통해서 이 문제를 해결할 수 있다.

#include 

using namespace std;

// 일반적인 '도형'을 상징하는 클래스
class Shape
{
public:
    void Move(double x, double y);
    virtual void Draw() const;

    Shape();
    Shape(double x, double y);

protected:
    double _x;
    double _y;
};
Draw() 함수앞에 virtual을 적어줌으로서 객체 타입에 맞는 Darw()함수가 호출된다.
  • virtual 키워드는 클래스의 정의 안쪽에서만 한 번 붙여주면 된다.
  • 클래스 밖에서 함수를 정의할 때는 virtual 키워드가 필요없다.



저작자 표시
신고

'컴퓨터 언어 > C++' 카테고리의 다른 글

예외 처리  (0) 2012.12.21
오버라이딩  (0) 2012.12.20
가상함수를 이용한 다형성 구현  (0) 2012.12.20
다중상속(Multiplex inheritance)  (0) 2012.12.20
접근제어 키워드  (0) 2012.12.20
포인터간의 형 변환, 레퍼런스간의 형변환  (0) 2012.12.20


티스토리 툴바