Part2::Ch 03. 상속 - 04. 추상 클래스, 순수 가상 함수

2025. 5. 4. 18:35Programming Language/C++

반응형

1. 추상클래스(Abstract Class)

추상 클래스(Abstract Class)란 하나 이상의 순수 가상 함수(pure virtual function)를 포함하는 클래스로 직접 객체를 생성할 수 없는 클래스다.

주로 공통 인터페이스를 정의하고 이를 상속받는 하위 클래스가 구체적인 동작을 구현하도록 강제하기 위해 사용한다

 

2. 순수 가상함수(pure virtual function)

순수 가상 함수(pure virtual function)란 자식 클래스에서 반드시 재정의(override)해야 하는 가상 함수로 구현 없이 선언만 되어 있는 함수이다.

순수 가상함수는 함수의 본체(body)가 없고, = 0으로 표시된다

 

1) 순수 가상함수의 문법

virtual 반환형 함수이름(매개변수) = 0;

================================================

class Animal {
public:
    virtual void speak() = 0; // 순수 가상 함수
};

 

3. 코드로 보는 추상 클래스

추상클래스에 대해 코드를 보기 전에 현실에서의 예시를 들어보자.

우리 주변에 있는 플라스틱은 어떻게 사용하냐에 따라서 많은 도구로 변신한다.

그 도구들은 각각 서로 별개의 기능을 가지고 있기 마련이다.

그러면 플라스틱이란 것만으로 각 도구의 기능을 구현해낼 수 없다.

그 도구가 됨으로써 비로소 칫솔이 될수도, 바구니가 될 수도, 당구공이 될 수 도 있는 것이다.

 

이것에 대해서 코드로 한번 작성해보자.

우선 플라스틱이라는 클래스를 하나 만들어보자.

이 플라스틱에 대한 기능을 알려주는 함수를 하나 만들어보자.

당장 이 함수에서는 어떤 기능도 넣어주지 않을 것이다.

이 함수가 순수 가상함수의 역할을 하게될 것이기 때문이다.

 

이제 이 Plastic을 가지고 만들수 있는 ToothBrush, Basket을 만들어보자.

그리고 이 도구들은 각각 플라스틱으로 부터 왔기에 플라스틱을 상속할것이다.

이때 각각의 도구들은 이제 기능 함수라는 기능을 오버라이딩 하게 될것이기에 플라스틱의 purpose 함수를 가상함수로 만들어주자.

여기서 생각해보면 플라스틱 자체에는 기능을 갖고 있지 않으며 이 기능이 만들어지는 도구마다 천차만별의 기능을 하게 될 것이기에 이걸 플라스틱 자체에서 선언하지 말고 순수 가상함수로 만들어줄것이다.

순수 가상함수의 생성

이렇게 Plastic이라는 클래스가 순수 가상함수가 생기는 순간 추상클래스가 된다.

그렇기에 해당 클래스는 객체로 만들어질 수 없다.

그리고 이렇게 가상 함수가 생성된 동시에 해당 클래스에는 가상 소멸자도 무조건 생성되어야만함(업케스팅을 할 경우 가상 소멸자를 만들지 않으면 자식 객체에 대한 소멸자를 부르지 않게 됨 )

그럼 이렇게 만든 클래스는 인스턴스화 할 수 없으니까 타입으로 사용할 수 없을까?

아니다, 추상클래스의 경우에는 다른 클래스를 가리키는 포인터나 레퍼런스로 사용이 될 수 있다.

그걸 보기 위해서 먼저 상속한 클래스에서 동일한 함수에 대해서 작성을 마쳐보자.

 

추상 클래스를 상속한 클래스에서 순수 가상 함수를 오버라이딩 하지 않으면 해당 클래스도 추상 클래스가 된다.

그렇기에 추상클래스로 사용하려는게 아니라면 추상 클래스를 상속한 클래스에서는 순수 가상 클래스를 오버라이딩해서 구현해줘야만 한다.

이렇게 구현되는 순간 객체 생성이 가능해짐을 확인할 수 있다.

이 내부에서는 ToothBrush의 기능에 대해서 출력하는 내용을 작성해주자.

추가로 함수 옆쪽에 override함을 작성해주자.

이렇게 하면 객체에서 해당 기능을 사용하면 

사용이 가능하다.

 

동일하게 Basket도 만들어주면

이렇게 잘 기능하는 것을 볼 수 있다.

 

그런데 여기서 Plastic만으로는 객체를 만들어서 사용은 불가능하지만

이런식으로 포인터나 참조의 타입으로는 사용이 가능하다는 것이다.

여기서 하나의 순수 가상 함수를 추가해주고

모든 상속된 클래스에도 각 구현을 해주자.

이제 각 가격을 반환하는 price라는 함수가 하나 생겼다.

 

그러면 이 가격의 평균을 구하는 클래스가 하나 생성 해주도록 하자.

해당 클래스에는 모든 값을 더해줄 멤버변수가 하나 존재하고 몇번 더해졌는지에 대한 count를 해주는 멤버 변수를 0으로 초기화하여 가지고 있도록 생성했다.

.

그리고 이 내부에 함수 오퍼레이터 오버로딩을 하나 해서 Plastic 객체를 참조의 형태로 받아주도록 하자.

그리고 내부에서 실행될때 마다 count를 올려주고 전체 값에 추가해주도록 한 후에

return으로 전체 값을 count로 나눈 평군을 반환하도록 구현했다.

한번 main에서 사용해본다면 

이렇게 추상클래스를 매개변수로 넘겨주면 관련 있는 클래스만 넘겨줄 수 있게 된다.

 

우리가 만들어둔 Plastic 처럼 

구체적인 구현없는 순수 가상 함수와 가상 소멸자만 존재하는 클래스를 인터페이스 라고 한다.

 

물론 이렇게 구현되어 있는 추상 클래스에서도 멤버 변수나 함수를 생성해줄 수 도 있다.

이렇게 추가하는 것도 가능하다.

 

 

반응형