💻프로그래밍 내용 정리/C++17

[C++ 8.2.1] 클래스 정의

이이프 2022. 10. 3. 11:18
728x90

클래스 정의

SpreadsheetCell 클래스의 첫 버전을 작성해보자.

여기서는 각 셀마다 숫자 하나만 저장하도록 정의한다.

class SpreadsheetCell
{
public:
    void setValue(double inValue);
    double getValue() const;
private:
    double mValue;
};

클래스 정의는 항상 class 키워드와 클래스 이름으로 시작한다.

C++에서 클래스 정의는 문장이다. 따라서 반드시 세미콜론(;)으로 끝나야 한다.

 

클래스 정의를 작성한 파일의 이름은 주로 클래스 이름과 똑같이 짓는다.

예를 들어 SpreadsheetCell 클래스 정의 파일은 SpreadsheetCell.h 파일에 저장한다.

 

 


 

1. 클래스 멤버

클래스는 여러 개의 멤버를 가질 수 있다.

멤버는 메서드, 생성자, 소멸자와 같은 함수(멤버 함수)일 수도 있고,

열거형, 타입 앨리어스, 중첩 클래스와 같은 변수(멤버 변수)일 수도 있다. 멤버 변수를 데이터 멤버라고도 부른다.

 

앞의 코드에서 SpreadsheetCell 클래스에서 지원하는 메서드를 다음과 같이 선언했다.

형식은 함수 프로토타입(함수 선언)과 같다.

void setValue(double inValue);
double getValue() const;

1장에서 설명했듯이 객체를 변경하지 않는 멤버 함수는 항상 const로 선언하는 것이 바람직하다.

 

앞의 코드에서 클래스의 데이터 멤버를 다음과 같이 선언했다. 형식은 변수 선언문과 같다.

double mValue;

클래스는 멤버 함수와 이들이 사용할 데이터 멤버를 정의한다.

이러한 멤버는 그 클래스에 대한 인스턴스객체 단위로 적용된다.

9장에서 설명할 정적 멤버는 예외적으로 클래스 단위로 적용된다.

 

클래스는 개념을 정의하고 객체는 클래스의 실체를 정의한다. 따라서 객체마다 mValue 변수의 값을 따로 갖는다.

멤버 함수의 구현 코드는 모든 객체가 공유한다.

클래스가 가질 수 있는 멤버 함수와 데이터 멤버스에는 제한이 없다.

또한 데이터 멤버의 이름과 멤버 함수의 이름이 같아도 된다.

 

 


 

2. 클래스 멤버

클래스의 각 멤버는 세 가지 접근 (제어) 제한자/지정자인 public, protected, private 중 하나로 지정한다.

한 번 지정된 접근 제한자는 다른 지정자로 변경하기 전까지 모든 멤버에 적용된다.

 

SpreadsheetCell 클래스에서 setValue()와 getValue() 메서드는 public으로 지정한 반면

데이터 멤버인 mValue는 private로 지정했다.

 

클래스에 접근 제한자를 따로 명시하지 않으면 private가 적용된다.

즉, 접근 제한자를 따로 지정하지 않고 선언한 모든 멤버의 접근 범위는 private가 적용된다.

예를 들어 public 접근 제한자를 setValue() 메서드 선언문 뒤로 옮기면 SetValue() 메서드의 접근 범위가 private로 바뀐다.

class SpreadsheetCell
{
    void setValue(double inValue); // 이렇게 하면 private가 적용된다.
public:
    double getValue() const;
private:
    double mValue;
};

 

C++에서는 struct도 class처럼 메서드를 가질 수 있다.

사실 struct의 디폴트 접근 제한자가 public이란 점을 제외하면 class와 같다.

예를 들어 앞서 작성한 SpreadsheetCell 클래스를 다음과 같이 struct로 작성할 수 있다.

struct SpreadsheetCell
{
    void setValue(double inValue);
    double getValue() const;
private:
    double mValue;
};

 

데이터 멤버는 누구나 접근할 수 있으며, 메서드가 없거나 개수가 적다면 관례상 class보다는 주로 struct로 정의한다.

예를 들어 다음과 같이 좌표를 구현하는 구조체를 정의할 때는 struct를 사용한다.

struct Point
{
    double x;
    double y;
};

 

세 가지 접근 제한자의 의미와 용도를 정리하면 다음 표와 같다.

접근자 의미 용도
public 객체의 public 멤버 함수나 데이터 멤버는
어디에서나 접근할 수 있다.
클라이언트가 사용할 동작(메서드).

private 또는 protected 데이터 멤버에
대한 접근 메서드(게터와 세터).
protected protected 멤버 함수나 데이터 멤버는 같은 클래스로 된 객체의 멤버 함수로 접근할 수 있다

또한 파생 클래스의 멤버 함수는 베이스 클래스의 protected 멤버에 접근할 수 있다.
외부 클라이언트가 사용하면 안 되는 헬퍼 메서드에 적용한다.
private private 멤버 함수나 데이터 멤버는 같은 클래스의 멤버 함수로만 접근할 수 있다.
파생 클래스의 멤버 함수는 베이스 클래스의 private 멤버에 접근할 수 없다.
기본적으로 모두 private로 지정한다.
특히 데이터 멤버라면 반드시 private로 지정한다. 파생 클래스만 게터나 세터에 접근하게 하려면 protected로 지정하고,
외부 클라이언트도 접근하게 하려면
public으로 지정한다.

 

 


 

3. 선언 순서

C++에서는 멤버와 접근 제한자를 선언하는 순서를 따로 정해두지 않았다.

데이터 멤버 앞에 멤버 함수를 선언해도 되고, private 뒤에 public을 선언해도 된다.

게다가 접근 제한자를 반복해서 지정해도 된다.

struct SpreadsheetCell
{
public:
    void setValue(double inValue);
private:
    double getValue() const;
public:
    double mValue;
};

물론 가독성을 위해 public, protected, private 멤버를 함께 묶어서 선언하는 것이 좋다.

 

 


 

4. 클래스 내부의 멤버 이니셜라이저

클래스를 정의할 때는 멤버 변수를 선언하는 동시에 초기화할 수 있다.

예를 들어 다음과 같이 SpreadsheetCell 클래스에서 mValue 멤버의 기본값을 0으로 초기화할 수 있다.

class SpreadsheetCell
{
    // 클래스 정의의 나머지 부분은 생략
private:
    double mValue = 0;
};