가상함수를 만드는 이유 :


    일반화된 부모 객체의 포인터 타입을 이용해 자식 객체의 함수를 부르고 싶은경우.

    

    ex )


    class   GRAPHIC_CARD

    {

        ...


    public:

        ...

        virtual void    put_pixel( int x, int y, COLOR color )

        {

            puts( "GRAPHIC_CARD::put_pixel" );

        }

    };


    class   NVIDIA

    {

        ...


    public:

        void    put_pixel( int x, int y, COLOR color ) // 자식들은 virtual 생략가능

        {

            puts( "NVIDIA::put_pixel" );

        }

    };


    class   ATI

    {

        ...


    public:

        void    put_pixel( int x, int y, COLOR color )

        {

            puts( "ATI::put_pixel" );

        }

    };


    class   ETC

    {

        ...


    public:

        //  put_pixel 미구현

    };



    GRAPHIC_CARD* video_cards[]

    {

        (GRAPHIC_CARD*)new NVIDIA,

        (GRAPHIC_CARD*)new ATI,

        (GRAPHIC_CARD*)new ETC,

    };

    for( auto card : video_cards )

        card->putpixel( 0, 0, BLACK );


    출력 )

        NVIDIA::put_pixel

        ATI::put_pixel

        GRAPHIC_CARD::put_pixel


    즉, 부모의 멤버함수인 GRAPHIC_CARD::put_pixel 을 자식의 put_pixel 이 override

    미구현된 경우, 부모의 멤버함수가 디폴트로 사용된다.



순수 가상 함수의 경우


    class   GRAPHIC_CARD

    {

        ...


    public:

        ...

        virtual void    put_pixel( int x, int y, COLOR color ) = 0;

    };


    마찬가지로 NVIDIA, ATI, ETC 를 정의했을 때, ETC 때문에 컴파일 에러가 난다.

    순수 가상함수는 디폴트 함수 정의가 없기 때문에 미구현 메서드가 있을때는 에러로 알려준다.

    즉, 순수가상함수는 자식객체에서 반드시 구현되어야 할 메서드를 약속하는데 사용된다.