[C++] 추상클래스

빵욱·2024년 3월 22일

추상클래스?

C++에서 추상클래스는 하나 이상의 순수 가상 함수를 포함하는 클래스이다.
순수 가상 함수 => 본체가 없으며 파생 클래스에서 반드시 구현해야 한다.
그래서 추상 클래스는 인스턴스화 될 수 없다.
C#, JAVA의 인터페이스 역확을 추상 클래스로 하면된다.

추상 클래스는 가상 함수, 순수 가상함수, 일반 함수, 멤버 변수, 정적 함수를 가질 수 있다.

  • 가상함수 : 파생클래스에서 오버라이드 가능. 순수 가상 함수가 아니므로 기본 구현을 제공할 수 있다.

  • 순수 가상 함수 : 파생클래스에서 반드시 구현해야 하는 함수.이 함수들이 클래스를 추상클래스로 만든다.
    final 키워드가 붙지 않은 이상은 반드시 재정의 해줘야한다.

  • 일반 함수 : 이러한 함수들은 오버라이드할 수 없다. 직접 구현된다.
    일반 함수는 파생 클래스에서 오버라이딩할 수 없고 파생 클래스에서 동일한 이름과 시그니처를 가진 함수를 정의한다면
    이는 새로운 함수를 제공하는 것으로 간주된다.
    오버로딩과 비슷한 개념일 수 있지만 실제로는 서로 다른 스코프에 속한 별개의 함수를 정의하는 것이라고 한다.

  • 멤버 변수 : 추상 클래스도 멤버 변수를 가질 수 있다.

  • 정적 함수 : 클래스 인스턴스 없이 호출될 수 있는 함수

순수 가상 함수 만드는 법.

함수 선언 끝에 = 0을 붙여서 만든다.

virtual void SetPrice(int myPrice) = 0;

fianl 키워드를 사용하면 재정의(오버라이드)가 불가능하다.

virtual void SetPrice(int myPrice) final; // 가상함수
virtual void SetPrice(int myPrice)= 0 final; // 순수 가상 함수

예제

class AbstractClass {
public:
    // 순수 가상 함수
    virtual void pureVirtualFunction() = 0;

    // 가상 함수
    virtual void virtualFunction() {
        std::cout << "This is a virtual function with an implementation." << std::endl;
    }

    // 일반 함수
    void normalFunction() {
        std::cout << "This is a normal function." << std::endl;
    }

    // 정적 함수
    static void staticFunction() {
        std::cout << "This is a static function." << std::endl;
    }
};

순수 가상 함수와 일반 함수

class Base {
public:
    void regularFunction() {
        std::cout << "Base regularFunction" << std::endl;
    }

    virtual void virtualFunction() = 0;
};

class Derived : public Base {
public:
	// 이 일반함수는 Derived 클래스의 함수.
    void regularFunction() {
        std::cout << "Derived regularFunction" << std::endl;
    }

    void virtualFunction() override {
        std::cout << "Derived virtualFunction" << std::endl;
    }
};

override 키워드

함수를 오버라이드할 때 꼭 override 키워드를 사용해야하는 것은 아니다.
하지만 사용하는 것이 좋은 관행이라고 한다.
override 를 사용하면

  • 오버라이드 의도 검증: 파생 클래스의 함수가 기반 클래스의 가상 함수를 실제로 오버라이드하는지 확인한다. 함수 시그니처가 정확히 일치하지 않는 경우(예: 매개변수 타입 불일치, 상수성 불일치 등), 컴파일러는 오류를 발생시킨다.

  • 기반 클래스 함수의 가상성 확인: override 키워드가 사용된 함수는 반드시 기반 클래스의 가상 함수를 오버라이드해야 한다. 만약 기반 클래스에 해당 시그니처의 가상 함수가 없다면 컴파일러는 오류를 발생시킨다.

class Base {
public:
    virtual void func();
};

class Derived : public Base {
public:
    void func() override; // 이 함수는 Base::func를 오버라이드함을 명시
};

override 키워드 사용은 가독성과 안정성을 높이는 좋은 방법이니 사용하도록 하자.

profile
rove drink eat

0개의 댓글