하나 이상의 순수 가상 함수를 가지는 클래스를 추상 클래스(Abstract Class)라고 한다. 추상 클래스는 동작이 정의되지 않은 멤버 함수를 가지고 있기 때문에 이 상태로는 인스턴스를 생성할 수 없다.
추상 클래스를 사용하는 실제 프로젝트의 예를 들어 보자. 워드 프로세서의 문서를 분석하는 기능을 캡슐화하여 클래스로 만들고자 한다. 이 클래스는 문서를 순서대로 읽으면서 문서에 속한 문단, 도표, 그림 등등의 요소를 추출해 내며 이렇게 분석한 결과는 출력, 인쇄, 다른 문서 형식으로의 변환, 검색 등에 사용될 것이다. 많이 사용되는 아래한글과 워드 문서에 대한 분석 클래스를 작성한다면 아마도 다음과 같은 멤버 함수의 목록이 만들어질 것이다.
문서라는 복잡한 대상을 분석하기 위해서는 메모리도 필요할 것이고 때로는 외부 라이브러리(XML 파서 등)의 도움이 필요하기도 하므로 분석 준비 과정이 필요하며 준비를 했으면 해제하는 과정도 당연히 필요하다. 그래서 Prepare, CleanUp 따위의 멤버 함수가 선언되어 있다. 또한 어떤 워드 프로세서 문서든지 문단으로 구성되어 있고 문단안에 도표와 그림이 있는 기본적인 구조는 동일하므로 ReadPara, ReadTable, ReadPicture 등의 함수들도 필요하다.
이 함수들의 내부 구현은 분석 대상 문서별로 상당히 다르겠지만 함수의 원형은 동일하다. 이 외에 문서 타입별로 고유한 데이터도 있을 수 있으므로 이런 데이터를 읽는 멤버 함수들도 필요할 것이다. 예를 들어 아래한글은 글맵시라는 문자 장식이 있고 워드에는 하이퍼 링크라는 것이 있다. 보다시피 두 클래스에는 중복되는 기능들이 아주 많이 있어 상위 클래스를 정의한 후 파생시킬 수 있다. Parser라는 이름으로 일반적인 분석기 클래스를 정의한다면 아마 다음과 같은 상속 계층이 만들어질 것이다.
공통되는 기능을 상위 클래스로 정의하는 것은 아주 일반적인 상속 기법이다. 자, 그럼 이때 만들어진 Parser 클래스는 과연 어떤 문서를 분석하는 클래스라고 할 수 있겠는가? 이 클래스는 단지 문서 분석기 클래스들의 공통된 부모일 뿐 실제로 세상에 존재하는 문서를 분석하는 기능을 가지지는 못한다. 왜냐하면 "문서"라는 추상적인 대상을 분석하는데 필요한 기능의 목록을 정의할 뿐이므로 구체적인 구현을 가질 수 없는 것이다.
ParseHwp나 ParseDoc 클래스는 구체적인 문서에 대한 분석 동작을 하지만 Parser는 기능이 너무 일반적이어서 이런 동작을 정의할 수 없다. 그래서 Parser의 멤버 함수들은 순수 가상 함수로 선언되어야 하며 따라서 Parser는 추상 클래스가 되는 것이다. 이 클래스의 역할은 문서 분석기가 가져야 할 필수 인터페이스의 목록을 정의한다. 만약 이후 훈민정음이나 HTML 문서에 대한 분석기를 추가해야 한다면 Parser로부터 상속받은 후 Parser가 선언한 순수 가상 함수를 반드시 재정의해야 한다.
Parser는 인터페이스 목록만 정의하고 파생 클래스는 상속 받은 가상 함수가 요구하는 구체적인 동작을 재정의할 의무를 가진다. 그래야 최소한의 요구 사항을 만족하는 문서 분석기가 될 수 있다. 이렇게 되면 Parser로부터 파생된 클래스를 사용하는 방법에 일관성이 생겨 어떤 종류의 문서 분석기든지 획일된 방법으로 사용할 수 있게 된다. 추상 클래스가 정의하는 인터페이스에 의해 복잡한 클래스 계층에 어떤 질서가 부여되는 것이다. 모든 분석기들은 공통의 조상을 가지므로 Parser * 타입으로 모든 분석기의 집합을 관리할 수 있으며 Parser * 타입의 인수를 받아들이는 함수는 임의의 분석기에 대한 다형적인 동작을 처리할 수 있다.
시간이 지난 후 이 프로젝트를 다시 분석할 때는 추상 클래스의 순수 가상 함수 목록만 봐도 프로젝트의 전체 구조를 한눈에 파악할 수 있다. 후임자에게 프로젝트를 인수하거나 팀작업을 할 때도 추상 클래스 자체가 워낙 설명적이어서 별다른 해설이 필요치 않다. 물론 그렇게 되려면 후임자나 팀원이 C++에 대한 기본 개념이 확립된 사람이어야 한다.
아주 다음에 배우게 되겠지만 COM의 인터페이스는 모든 멤버 함수들이 순수 가상 함수인 완전 추상 클래스로 정의되어 있다. COM은 재사용 가능한 컴포넌트를 정의하고 컴포넌트끼리 통신할 수 있는 방법이며 ActiveX, DirectX 등 최신 기술의 기반 문법이다.