Nested classes
| 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 | ||||||||||||||||
|
||||||||||||||||
| 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 | ||||||||||||||||
class/struct 또는 union 의 선언이 다른 클래스 내부에 나타날 수 있습니다. 이러한 선언은 중첩 클래스(nested class) 를 선언합니다.
설명
중첩 클래스의 이름은 외부 클래스의 범위 내에 존재하며, 중첩 클래스의 멤버 함수에서 이름 검색(name lookup)은 중첩 클래스의 범위를 검사한 후 외부 클래스의 범위를 방문합니다. 외부 클래스의 다른 멤버와 마찬가지로, 중첩 클래스는 외부 클래스가 접근할 수 있는 모든 이름(private, protected 등)에 접근할 수 있지만, 그 외에는 독립적이며 외부 클래스의
this
pointer
에 대한 특별한 접근 권한을 갖지 않습니다. 중첩 클래스의 선언은 비정적 멤버에 대한
일반적인 사용 규칙
을 따라 외부 클래스의 모든 멤버를 사용할 수 있습니다.
int x, y; // 전역 변수 class enclose // 외부 클래스 { // 참고: private 멤버 int x; static int s; public: struct inner // 중첩 클래스 { void f(int i) { x = i; // 오류: 인스턴스 없이 비정적 enclose::x에 쓸 수 없음 int a = sizeof x; // C++11까지 오류, // C++11에서 OK: sizeof의 피연산자는 평가되지 않으며, // 비정적 enclose::x의 이 사용은 허용됨 s = i; // OK: 정적 enclose::s에 할당 가능 ::x = i; // OK: 전역 x에 할당 가능 y = i; // OK: 전역 y에 할당 가능 } void g(enclose* p, int i) { p->x = i; // OK: enclose::x에 할당 } }; };
Friend 함수가 중첩 클래스 내부에서 정의된 경우, 중첩 클래스 내부에서 정의된 멤버 함수의 본문에서 조회 시 바깥쪽 클래스의 private 멤버를 찾을 수 있더라도, 바깥쪽 클래스의 멤버에 대한 특별한 접근 권한을 갖지 않습니다.
중첩 클래스의 멤버에 대한 클래스 외부 정의는 외부 클래스의 네임스페이스에 나타납니다:
struct enclose { struct inner { static int x; void f(int i); }; }; int enclose::inner::x = 1; // 정의 void enclose::inner::f(int i) {} // 정의
중첩 클래스는 전방 선언될 수 있으며, 동일한 외부 클래스 본문 내에서나 외부에서 나중에 정의될 수 있습니다:
class enclose { class nested1; // 전방 선언 class nested2; // 전방 선언 class nested1 {}; // 중첩 클래스 정의 }; class enclose::nested2 {}; // 중첩 클래스 정의
중첩 클래스 선언은 멤버 접근 지정자를 따르며, private 멤버 클래스는 외부 클래스의 범위 밖에서는 이름을 사용할 수 없지만, 해당 클래스의 객체는 조작될 수 있습니다:
class enclose { struct nested // private 멤버 { void g() {} }; public: static nested f() { return nested{}; } }; int main() { //enclose::nested n1 = enclose::f(); // 오류: 'nested'는 private입니다 enclose::f().g(); // OK: 'nested'를 명시적으로 언급하지 않음 auto n2 = enclose::f(); // OK: 'nested'를 명시적으로 언급하지 않음 n2.g(); }
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 45 | C++98 |
중첩 클래스의 멤버들이
외부 클래스와 그 friend들에 접근할 수 없음 |
외부 클래스의 다른 멤버들과
동일한 접근 권한을 가짐 (CWG 이슈 #8과 #10도 함께 해결됨) |
참고문헌
- C++23 표준 (ISO/IEC 14882:2024):
-
- 11.4.12 중첩 클래스 선언 [class.nest]
- C++20 표준(ISO/IEC 14882:2020):
-
- 11.4.10 중첩 클래스 선언 [class.nest]
- C++17 표준 (ISO/IEC 14882:2017):
-
- 12.2.5 중첩 클래스 선언 [class.nest]
- C++14 표준(ISO/IEC 14882:2014):
-
- 9.7 중첩 클래스 선언 [class.nest]
- C++11 표준 (ISO/IEC 14882:2011):
-
- 9.7 중첩 클래스 선언 [class.nest]
- C++98 표준 (ISO/IEC 14882:1998):
-
- 9.7 중첩 클래스 선언 [class.nest]