[cpp] Pure Virtual Function

minjubyeon·2025년 5월 20일

cpp

목록 보기
12/26
class Shape {
public:
    bool bValid;
public:
    virtual double GetArea() const = 0;
};

→ return 타입이 double이고, parameter는 없으며 const 타입의 virtual 함수 GetArea를 선언한다. 이때 = 0;을 통해 이 함수가 순수가상함수임을 명시하여, 해당 클래스가 추상 클래스가 되도록 한다.

1. Pure Virtual Function

함수 뒤에 = 0을 붙이면 순수가상함수이다. 함수의 구현(본문)은 없고, 선언만 한다. 이 함수는 자식 클래스가 반드시 override(재정의) 해야 한다. 만약 자식 클래스가 이 함수를 구현하지 않으면, 그 자식 클래스도 추상 클래스가 된다.



2. Abstract Class

하나 이상의 순수가상함수를 포함하는 클래스는 추상 클래스가 된다. 추상 클래스는 instance를 만들 수 없다. 공통된 인터페이스만 정의하고, 구체적인 구현은 파생 클래스가 한다. interface 역할(틀, 계약)을 하며, 자식 클래스에게 특정 함수 구현을 강제한다.



구분설명
순수가상함수virtual 함수명() = 0 형태로, 반드시 자식 클래스가 구현해야 함
추상 클래스하나 이상의 순수가상함수를 가진 클래스 (객체 생성 불가)
목적자식 클래스에게 함수 구현을 강제하고, 다형성을 지원함
사용 예도형 클래스(Shape)는 GetArea()를 구현하지 않지만, 자식 클래스인 Rectangle, Triangle 등에서 각각 다르게 구현


📦 예시

class Shape {
public:
    virtual double GetArea() const = 0; // 순수가상함수 → Shape는 추상 클래스
};

class Rectangle : public Shape {
    double width, height;
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    double GetArea() const override { return width * height; }
};

int main() {
    // Shape s; // ❌ 오류: 추상 클래스는 객체 생성 불가
    Rectangle r(3, 4);
    Shape& s = r; // ✅ 업캐스팅
    std::cout << s.GetArea(); // 12 출력
}


🔍 Shape class가 필요한 이유?

겉보기엔 Shape 클래스는 아무 기능도 없고 직접 객체도 못 만드니까 "왜 만들지?" 하는 의문이 든다. 하지만 Shape class는 매우 중요한 역할을 한다.

이유설명
1. 공통 인터페이스 제공모든 도형(Rectangle, Triangle 등)이 반드시 GetArea()를 갖도록 강제
2. 다형성(Polymorphism) 지원Shape* 또는 Shape& 타입 하나로 다양한 도형을 처리 가능
3. 확장성 있는 설계새로운 도형(예: Circle, Polygon 등)을 쉽게 추가 가능
4. 코드 재사용과 일관성같은 방식으로 모든 도형의 넓이를 계산하거나 처리 가능


🔍 만약 Shape Class가 없다면?

  • 도형마다 다른 함수 이름을 가질 수 있다. (GetArea, CalcArea, Area 등)
  • 다형성으로 한꺼번에 처리할 수 없다.
  • 도형마다 따로 코드를 작성해야 하므로 유지보수가 힘들어진다.


🔚 결론

Shape 클래스는 비록 직접 쓸 수는 없지만, 모든 도형의 '틀'을 정의하고,통일된 방식으로 처리하기 위한 핵심 역할을 한다.

👉 Shape는 "도형이라는 개념을 설계적으로 통합"하는 데 꼭 필요한 Abstract Interface class다.



3. 추가 설명

Shape* 또는 Shape& 타입으로 다양한 도형을 처리할 수 있다?


3.1 다형성

부모 클래스 포인터(Shape*)나 참조(Shape&)를 통해 자식 클래스의 오버라이드된 함수를 호출하는 기능입니다.

이 기능 덕분에 Rectangle, Triangle, Circle 등 다양한 도형을
한 가지 타입(Shape)으로 통합해서 처리할 수 있습니다.


📦 예시 (Shape*)

Shape* pShape1 = new Rectangle(3, 4);  // 사각형 객체를 Shape 포인터로 저장
Shape* pShape2 = new Triangle(3, 4, 5); // 삼각형 객체도 Shape 포인터로 저장

std::cout << pShape1->GetArea() << std::endl; // Rectangle의 GetArea 호출
std::cout << pShape2->GetArea() << std::endl; // Triangle의 GetArea 호출

→ pShape1과 pShape2는 모두 Shape* 타입이지만, 실제로는 각각 Rectangle과 Triangle 객체를 가리키고 있으므로 자식 클래스의 GetArea() 함수가 실행된다.

이게 바로 다형성입니다.


📦 예시 (Shape&)

void PrintArea(Shape& s) {
    std::cout << s.GetArea() << std::endl;
}

Rectangle r(3, 4);
Triangle t(3, 4, 5);

PrintArea(r); // Rectangle의 GetArea() 실행
PrintArea(t); // Triangle의 GetArea() 실행

→이 경우는 포인터 대신 참조(&)를 사용했을 뿐이고, 동작은 똑같이 자식 클래스의 GetArea()가 실행됩니다.



profile
안녕하세요.

0개의 댓글