Namespaces
Variants

Abstract class

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

인스턴스화할 수 없지만 기본 클래스로 사용할 수 있는 추상 타입을 정의합니다.

목차

구문

pure virtual 함수는 다음 구문을 갖는 virtual function declarator 입니다:

선언자 가상 지정자  (선택 사항) = 0

여기서 = 0 시퀀스는 pure-specifier 로 알려져 있으며, declarator 바로 뒤나 선택적 virt-specifier ( override 또는 final ) 뒤에 나타납니다.

pure-specifier 는 멤버 함수 정의나 friend 선언에 나타날 수 없습니다.

struct Base
{
    virtual int g();
    virtual ~Base() {}
};
struct A : Base
{
    // OK: 세 개의 멤버 가상 함수를 선언하며, 그 중 두 개는 순수 가상 함수입니다
    virtual int f() = 0, g() override = 0, h();
    // OK: 소멸자도 순수 가상 함수로 선언할 수 있습니다
    ~A() = 0;
    // 오류: 함수 정의에 순수 지정자를 사용할 수 없습니다
    virtual int b() = 0 {}
};

추상 클래스 는 최소한 하나의 함수를 정의하거나 상속받으며, 해당 함수의 최종 오버라이더 순수 가상 함수 인 클래스입니다.

설명

추상 클래스는 일반적인 개념(예: Shape, Animal)을 나타내는 데 사용되며, 구체적인 클래스(예: Circle, Dog)의 기본 클래스로 사용될 수 있습니다.

추상 클래스의 객체는 생성될 수 없으며(추상 클래스를 파생한 클래스의 기본 하위 객체는 제외), 추상 클래스 타입인 비정적 데이터 멤버는 선언될 수 없습니다.

추상 타입은 매개변수 타입, 함수 반환 타입, 또는 명시적 변환의 타입으로 사용될 수 없습니다 (이는 정의 지점과 함수 호출 지점에서 확인됩니다. 함수 선언 지점에서는 매개변수와 반환 타입이 불완전할 수 있기 때문입니다).

추상 클래스에 대한 포인터와 참조자를 선언할 수 있습니다.

struct Abstract
{
    virtual void f() = 0;  // 순수 가상 함수
}; // "Abstract"는 추상 클래스
struct Concrete : Abstract
{
    void f() override {}   // 비순수 가상 함수
    virtual void g();      // 비순수 가상 함수
}; // "Concrete"는 비추상 클래스
struct Abstract2 : Concrete
{
    void g() override = 0; // 순수 가상 오버라이더
}; // "Abstract2"는 추상 클래스
int main()
{
    // Abstract a;   // 오류: 추상 클래스
    Concrete b;      // OK
    Abstract& a = b; // 추상 기본 클래스를 참조하는 것은 OK
    a.f();           // Concrete::f()로의 가상 디스패치
    // Abstract2 a2; // 오류: 추상 클래스 (g()의 최종 오버라이더가 순수 가상 함수임)
}

순수 가상 함수의 정의는 제공될 수 있으며 (순수 가상 함수가 소멸자 인 경우 반드시 제공되어야 함): 파생 클래스의 멤버 함수들은 정규화된 함수 id를 사용하여 추상 기반 클래스의 순수 가상 함수를 호출할 수 있습니다. 이 정의는 반드시 클래스 바디 외부에서 제공되어야 합니다 (함수 선언 구문은 순수 지정자 = 0 와 함수 본문을 동시에 허용하지 않습니다).

추상 클래스의 생성자나 소멸자에서 순수 가상 함수에 대한 가상 호출을 수행하는 것은 (정의가 있는지 여부와 관계없이) 정의되지 않은 동작입니다.

struct Abstract
{
    virtual void f() = 0; // 순수 가상 함수
    virtual void g() {}   // 비순수 가상 함수
    ~Abstract()
    {
        g();           // OK: Abstract::g() 호출
        // f();        // 정의되지 않은 동작
        Abstract::f(); // OK: 비가상 호출
    }
};
// 순수 가상 함수의 정의
void Abstract::f()
{
    std::cout << "A::f()\n";
}
struct Concrete : Abstract
{
    void f() override
    {
        Abstract::f(); // OK: 순수 가상 함수 호출
    }
    void g() override {}
    ~Concrete()
    {
        g(); // OK: Concrete::g() 호출
        f(); // OK: Concrete::f() 호출
    }
};

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 390 C++98 정의되지 않은 순수 가상 소멸자가 호출될 수 있었음 이 경우 정의가 필요함
CWG 2153 C++98 pure-specifier 가 friend 선언에 나타날 수 있었음 금지됨

참고 항목