Abstract class
인스턴스화할 수 없지만 기본 클래스로 사용할 수 있는 추상 타입을 정의합니다.
목차 |
구문
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 선언에 나타날 수 있었음 | 금지됨 |