블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2797)
Unity3D (853)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (61)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

[ 가상함수(Virtual Function) ]

1. 가상함수 개요

■ 가상함수(Virtual Function)란?

- 실행시 사용된 객체에 의해 실행 코드가 결정되는 함수

- 지정자 virtual로 선언됨 지정자 virtual은 선언문에 존재함.

class Animal {

  public :

    virtual void breathe();

};

 

class Fish : public Animal {

   public :

    virtual void breathe();

};

 

■ 가상 함수의 호출

- 기반클래스의 포인터가 파생클래스의 객체를 가리킬 때, 그 포인터를 통해 가상함수를 호출하면 파생 클래스에서 재정의한 함수가 호출됨.

Animal* a = new Fish;

a -> breathe();    // Fish::breathe 호출

→ a->breathe(); 는 Fish::breathe 를 호출함. 즉, a->breathe(); 는 함수명으로는 Animal::breathe를 호출하지만, 내용으로는 Fish::breathe 가 호출되는 것임.

 

■ 기반클래스의 멤버함수가 virtual 을 갖고 있을 때

- 파생클래스에서 재정의한 함수는 virtual 을 생략해도 저절로 가상함수가 됨.

- 그러나 기반클래스의 가상 함수를 파생클래스에서 재정의할  때도 virtual 을 명시해주는 것이 관례임. (소스코드 이해가 수월하기 위해서...)

 

2. 가상함수의 특징

■ 동적바인딩(Dynamic Binding)

- 가상함수는 동적결합(Dynamic Binding)을 함. (코드만 봐서는 어떤 코드가 실행될지 정해지지 않은 상태. 즉, 객체를 생성하는 시점에 생성조건에 따라 실행코드가 결정된다.)

- 일반함수는 정적 결합을 하는 반면, 가상 함수는 동적 결합을 함.

 

■ 가상함수(동적 바인딩)의 장단점

- 장점 : 실행시 다형성(Runtime Polymorphism) 이라는 융통성을 갖게 됨. (상황에 생성하는 조건에 따라 실행 코드를 변경할 수 있다.)

- 단점 : 가상함수를 사용하면 실행속도에서는 손해

  

3. 가상 함수 테이블 (Virtual Function Table)

■ vtable (Virtual Function Table) 이란?

- 가상 함수에 대한 포인터 배열

- 가상 함수를 사용하는 클래스의 각 객체는 vtable을 가리키는 vptr이라는 숨겨진 포인터를 갖고 있음.

- 가상함수를 포함한 클래스의 객체를 생성할 때 vtable이 만들어짐.

- 객체에서 가상함수를 호출하면 vptr를 통해 vtable에 있는 해당함수를 찾아 수행시킴.

 

■ 파생클래스에서의 vtable

- 기반클래스의 객체로부터 vtable을 물려 받아 수정 및 확장함.

- 파생클래스에서 재정의한 가상함수가 있다면 기반클래스의 가상 함수에 대한 포인터가 들어 있던 곳을 파생클래스에서 재정의한 가상함수에 대한 포인터로 변경함.

- 기반클래스의 포인터가 파생클래스의 오브젝트를 가리킬 때 그 포인터를 통해 가상 함수를 호출하면 파생클래스에서 수정한 vtable 을 사용하게 되므로 파생 클래스에서 재정의한 함수가 호출됨.

 

4. 가상 소멸자

■ 상속 관계에서 기반클래스의 포인터가 파생클래스의 동적 객체를 가리킬 때 그 포인터를 통해 동적 객체를 제거하면...?

기본적으로 기반 클래스의 소멸자만 호출되고 파생 클래스의 소멸자는 호출되지 않음.

class Animal {

};

 

class Fish : public Animal {

};

 

Animal* a = new Fish;

delete a;

 

■ 기반클래스의 포인터가 파생클래스의 동적 객체를 가리키고, 그 포인터를 통해 동적 객체를 제거했을 때 파생클래스의 소멸자까지 호출되도록 하려면...?

기반 클래스의 소멸자를 다음과 같이 가상 소멸자(Virtual Destructor)로 만들어야 함.

class Animal {

  public :

    Animal();

    virtual ~Animal();

};

 

class Fish : public Animal {

  public :

    Fish();

    virtual ~Fish();

};

 

Animal* a = new Fish;

delete a;

→ delete a;는 Animal::~Animal 뿐만 아니라 Fish::~Fish 도 호출함.

 

[ 순수가상함수(Pure Virtual Function) ]

1. 순수 가상 함수

■ 순수 가상 함수 (Pure Virtual Function) 란?

- 선언만 있고 정의가 없는 가상 함수

- 파생 클래스에서 재정의할 것으로 예상되는 함숭에 대해 미리 호출 계획을 세워 두기 위해 정의.

 

■ 가상함수를 순수 가상함수로 만드는 방법

- 다음의 예와 같이 선언시 0을 지정하면 됨.

- 여기서 '=0'은 Pure Specifier임.

class Animal {

  public :

    virtual void breathe() = 0;

};

 

class Fish : public Animal {

  public :

    Fish();

    virtual void breathe();

};

→ Animal::breathe 는 순수 가상함수임. Animal::breathe 는 함수명만 제공하고, 내용은 Fish::breathe 에서 제공하게 됨.

 

2. 추상클래스 (Abstract Class)

■ 추상클래스란?

- 순수 가상함수를 포함하고 있는 클래스.

- 파생클래스의 행동양식을 미리 설계하기 위한 기반클래스임.

- 일반적으로 순수 가상함수를 통해 인터페이스를 제공하고 파생클래스에서 그 인터페이스를 구현하게 됨.

class Animal { // 추상클래스 Animal

  public :

    virtual void breathe() = 0;

};

 

■ 추상클래스의 특징

- 추상클래스의 객체를 생성하는 것은 불가능. ∵ 정의되지 않은 함수를 가지고 있기 때문...

- 추상클래스는 파생클래스를 정의하여 순수가상함수를 구현하였을 때 객체를 생성할 수 있다.

- 추상클래스의 포인터를 선언하는 것은 가능함.

- 추상클래스의 포인터는 흔히 파생 클래스의 객체를 가리키게 되는데, 추상클래스의 포인터가 파생클래스의 객체를 가리킬 때 그 포인터를 통해 가상함수를 호출하면 파생클래스에서 재정의한 함수가 호출됨.

Animal* a = new Fish;

a -> breathe(); // 추상클래스 Animal

delete a;

 

2. 순수 가상함수의 재정의

■ 순수 가상함수의 재정의

- 순수 가상함수는 사용하기 전에 반드시 재정의해야 함.

- 만일 기반 클래스가 순수 가상 함수를 포함하고 있는데 파생 클래스에서 그것을 재정의하지 않는다면 그 파생 클래스도 추상 클래스가 됨.

→ 기반클래스 뿐만 아니라, 그 파생클래스의 객체를 생성하는 것도 불가능 함.

class Animal { // 추상클래스 Animal

  public :

    virtual void breathe() = 0;

};

 

class Fish : public Animal {

  public :

    void swim();

};

 

Animal* a = new Animal; // error

Animal* f = new Fish;  // error

 

출처 : http://blog.daum.net/embedded-seo/449971


반응형
Posted by blueasa
, |