프로그래밍 언어/C & C++ 정리

C++ 20 중첩 클래스

뽀또치즈맛 2025. 4. 7. 20:41

 

중첩 클래스


클래스 정의에는 데이터 멤버와 멤버 함수 뿐만 아니라
중첩 클래스, 구조체, 타입 앨리어스(typedef), 열거 타입(enum)
도 선언할 수 있다.

클래스 안에서 선언한 모든 것은
해당 클래스의 스코프로 제한된다.

public으로 선언한 멤버를 클래스 외부에서 접근할 때는
ClassName::과 같이 스코프 지정 연산자를 붙여야 한다.

클래스 정의 안에서 다른 클래스를 정의할 수도 있다.
예를 들어 SpreadsheetCell 클래스를
Spreadsheet 클래스 안에서 접근할 수 있다.
그러면 Spreadsheet 클래스의 일부분이 되기 때문에
이름을 간단히 cell이라고 붙여도 된다.
예를 들면 다음과 같다.

export class Spreadsheet
{
   public :
       class Cell
       {
          public :
              Cell() = default;
              Cell(double initialize);
              // 코드 생략
       };
      
       Spreadsheet(size_t width, size_t height,
          const SpreadsheetApplicatiom);
       // 코드 생략
}



Spreadsheet 안에 Cell클래스를 정의했기 때문에
Spreadsheet클래스 밖에서도 Cell을 얼마든지 참조할 수 있다.
물론 그 앞에 Spreadsheet::라고 스코프를 지정해야 한다.
이 규칙은 메서드 정의에도 똑같이 적용된다.
예를 들어 Cell의 생성자의 중에서
double타입 인수를 받는 버전을 다음과 같이 정의할 수 있다.

Spreadsheet::Cell::Cell(double initialVal)
   : m_value
{
    // 코드 생략
}



이렇게 스코프 지정 연산자를 붙이는 규칙은
Spreadsheet 클래스 안에 있는 메서드의 리턴 타입에도 적용된다.
단, 매개변수는 적용되지 않는다.

Spreadsheet::Cell& Spreadsheet::getCell(size_t x, size_t y)
{
    verityCoordinate(x, y);
    return m_cells[x][y];
}


Cell 정의 전체를 Spreadsheet 클래스 안에서
정의하면 Spreadsheet 클래스 정의 코드가 너무 길어진다.
이럴 때는 다음과 같이
Spreadsheet 클래스에서 Cell을 선언만 하고(=전방 선언문만 적고)
구체적인 정의 코드는 따로 작성할 수도 있다.


export class Spreadsheet
{
public:
    class Cell;

    Spreadsheet(size_t width, size_t height, const SpreadsheetApplication theApp);
    // 코드 생략
};

class Spreadsheet::Cell
{
public:
    Cell() = default;
    Cell(double initialValue);
};




중첩 클래스도 일반 클래스와 똑같이 접근 제한 규칙을 사용한다.
중첩 클래스의 private이나 protected로 선언하면
중첩 클래스를 담고있는 클래스에서만 접근할 수 있다.
중첩 클래스는 이를 담고있는 클래스의
private 나 protected 모두 접근할 수 있지만,
반면 중첩 클래스를 담고있는 클래스는
중첩 클래스의 public에만 접근할 수 있다.