추상 클래스 및 순수 가상 함수

추상 클래스는 일반 요소를 작성하는 데 사용되며, 일반 요소는 보다 구체적인 파생 클래스를 작성하는 데 사용됩니다. 추상 클래스는 일부 다른 클래스의 기준 클래스로만 사용할 수 있으므로 추상 클래스 유형의 개체를 만들 수 없습니다.

하나 이상의 순수 가상 함수를 포함하는 클래스는 추상적입니다. 따라서 추상 클래스에서 파생된 클래스는 모든 순수 가상 함수를 구현해야 하며, 그렇지 않으면 추상 클래스도 됩니다.

가상 함수는 순수 지정자 구문을 사용하여 "순수"로 선언됩니다. 공통 기능을 제공하기 위해 만들어진 CAnimal 클래스의 예를 생각해 보십시오. CAnimal 유형의 개체는 실용적으로 사용하기에는 너무 일반적입니다. 따라서, CAnimal은 추상적 클래스의 좋은 예입니다.

class CAnimal
  {
public:
                      CAnimal();     // 구성자
   virtual void       Sound() = 0;   // 순수 가상 함수
private:
   double             m_legs_count;  // 동물의 다리 수
  };

여기서 Sound()는 순수 가상 함수 PURE(=0)의 지정자로 선언되므로 순수 가상 함수입니다.

순수 가상 함수는 PURE 지정자가 (=NULL) 또는 (=0)으로 설정된 가상 함수입니다. 추상 클래스 선언 및 사용 예제:

class CAnimal
  {
public:
   virtual void       Sound()=NULL;   // PURE 메서드, 파생 클래스에서 재정의되어야 합니다. CAinimal은 이제 추상이므로 만들 수 없습니다.
  };
//--- 추상 클래스에서 파생됨
class CCat : public CAnimal
 {
public:
  virtual void        Sound() { Print("Myau"); } // PURE가 재정의되었습니다. CCat은 추상이 아니며 만들 수 있습니다.
 };
 
//--- 잘못된 사용 예
new CAnimal;         // 'CAnimal' 오류 - 컴파일러에서 "추상 클래스를 예시할 수 없음" 오류를 반환합니다.
CAnimal some_animal; // 'CAnimal' 오류 - 컴파일러에서 "추상 클래스를 예시할 수 없음" 오류를 반환합니다.
 
//--- 적절한 사용 예
new CCat;  // 오류 없음 - CCat 클래스가 추상이 아닙니다
CCat cat;  // 오류 없음 - CCat 클래스가 추상이 아닙니다

 
추상 클래스에 대한 제한

추상 클래스 생성자가 (직접 또는 간접적으로) 순수 가상 함수를 호출하는 경우 결과는 정의되지 않습니다.

//+------------------------------------------------------------------+
//| 추상 기준 클래스                                           |
//+------------------------------------------------------------------+
class CAnimal
  {
public:
   //--- 순수 가상 함수
   virtual void      Sound(void)=NULL;
   //--- 함수
   void              CallSound(void) { Sound(); }
   //--- 구성자
   CAnimal()
    {
     //--- 가상 메서드의 명시적 호출
     Sound();
     //--- 암시적 호출(세 번째 함수 사용)
     CallSound();
     //--- 생성자 및/또는 소멸자는 항상 자체 함수를 호출합니다,
     //--- 가상이고 파생 클래스에서 호출된 함수에 의해 재정의된 경우에도
     //--- 호출된 함수가 순수 가상이면
     //--- 이 호출은 심각한 런타임 오류를 발생시킵니다: "순수 가상 함수 호출"
    }
  };

그러나 추상 클래스의 생성자와 소멸자는 다른 멤버 함수를 호출할 수 있습니다.