메서드 정의 방법
앞서 정의한 SpreadsheetCell 클래스만으로도 이 클래스의 객체를 충분히 생성할 수 있다.
하지만 setValue()나 getValue() 메서드를 호출하면 이 메서드가 정의되지 않았다는 링커 에러가 출력된다.
클래스 정의에서 메서드의 프로토타입만 선언했을 뿐 구현 코드를 작성하지 않았기 때문이다.
클래스 정의는 주로 해더 파일에 작성하고,
메서드 정의는 소스 파일에 작성한 뒤 소스 파일에서 #include 문으로 해더 파일을 불러오는 방식으로 사용한다.
SpreadsheetCell 클래스의 두 메서드를 다음과 같이 정의한다.
#include "SpreadsheetCell.h"
void SpreadsheetCell::setValue(double inValue)
{
mValue = inValue;
}
double SpreadsheetCell::getValue() const
{
return mValue;
}
이 코드를 잘 보면 메서드 이름 앞에 클래스 이름과 콜론 두 개가 붙었다.
void SpreadsheetCell::setValue(double inValue)
여기서 ::를 스코프 지정 연산자라 부른다.
컴파일러가 이 코드를 보면 여기 나온 setValue() 메서드는 SpreadsheetCell 클래스에 속한다는 것을 알 수 있다.
1. 데이터 멤버 접근 방법
setValue()나 getValue() 메서드 같은 비정적 멤버는 항상 클래스가 아닌 객체에 대해 실행된다.
다시 말해 이런 메서드는 클래스에 정의된 데이터 멤버 중 현재 객체에 속한 멤버에 대해 접근한다.
예를 들어 어떤 객체든 앞에서 정의한 setValue() 메서도를 호출하면,
다음과 같이 자기 객체에 있는 mValue 변수의 값을 변경한다.
mValue = inValue;
다른 두 객체에 대해 각각 한 번씩 setValue()를 호출하면 실행되는 코드는 같지만 각자 속한 객체의 변숫값을 변경한다.
2. 다른 메서드 호출하기
메서드는 같은 클래스에 정의된 다른 메서드도 호출할 수 있다.
예를 들어 SpreadsheetCell 클래스를 확장한다고 하자.
실제 스프레드시트 애플리케이션은 셀 안에 숫자뿐만 아니라 텍스트 데이터도 넣을 수 있다.
텍스트 값을 가진 셀을 숫자로 해석하고 싶다면 텍스트를 숫자로 변환해준다.
이때 텍스트로 표현한 숫자가 올바르지 않다면 그 셀의 값을 무시한다.
확장된 예제에서는 셀에 담긴 스트링이 정상적인 숫자를 표현하지 않으면 0으로 변환한다.
SpreadsheetCell 클래스에 텍스트 데이터를 지원하도록 수정한 첫 번째 버전은 다음과 같다.
#include <string>
#include <string_view>
class SpreadsheetCell
{
public:
void setValue(double inValue);
double getValue() const;
void setString(std::string_view inString);
std::string getString() const;
private:
std::string doubleToString(double inValue) const;
double stringToDouble(std::string_view inString) const;
double mValue = 0;
};
이 코드는 C++17부터 추가된 std::string_view 클래스를 사용한다.
현재 사용하는 컴파일러가 C++17을 지원하지 않는다면 std::string_view를 const std::string&로 바꾼다.
이렇게 하면 mValue를 double로만 저장한다.
클라이언트가 이 데이터 멤버를 string 값으로 설정하면 double로 변환된다.
입력한 텍스트가 정상적인 숫자를 표현하지 않으면 0.0으로 설정된다.
이 버전의 클래스 코드는 셀에 텍스트 값을 설정하고 가져오는 메서드 두 개,
double과 string 값을 상호 변환하는 private 헬퍼 메서드 두 개를 추가로 정의했다.
메서드의 구현 코드는 다음과 같다.
#include "SpreadsheetCell.h"
using namespace std;
void SpreadsheetCell::setValue(double inValue)
{
mValue = inValue;
}
double SpreadsheetCell::getValue() const
{
return mValue;
}
void SpreadsheetCell::setString(string_view inString)
{
mValue = stringToDouble(inString);
}
string SpreadsheetCell::getString() const
{
return doubleToString(mValue);
}
string SpreadsheetCell::doubleToString(double inValue) const
{
return to_string(inValue);
}
double SpreadsheetCell::stringToDouble(string_view inString) const
{
return strtod(inString.data(), nullptr);
}
여기서 doubleToString() 메서드는 6.1과 같은 값을 '6.100000'이란 스트링으로 변환한다.
그런데 private 헬퍼 메서드로 구현했기 때문에 내부 변환 방식이 달라져도 클라이언트 코드를 수정할 필요가 없다.
'💻프로그래밍 내용 정리 > C++17' 카테고리의 다른 글
[C++ 8.2.3] 객체 사용법 (0) | 2022.10.03 |
---|---|
[C++ 8.2.2-2] this 포인터 (0) | 2022.10.03 |
[C++ 8.2.1] 클래스 정의 (0) | 2022.10.03 |
[C++ 7.5.1] 메모리 누수, 비주얼 C++을 이용한 메모리 누수 탐지 및 수정 방법 (0) | 2022.10.03 |
[C++ 7.4.3] weak_ptr (0) | 2022.10.03 |