어떤 경우에는 클래스의 객체별로 변수를 따로따로 가지는 것이 너무 중복되거나 의도에 맞지 않을수도 있다.
어떤 데이터 멤버가 특정 클래스에 종속되기는 하지만 객체별로 따로따로 복제본을 가지는 것은 불합리할 수 있다.
이런 경우를 위해 C++에서는 static 데이터 멤버를 지원한다.
static 데이터 멤버는 C에서의 전역변수와 유사하나 특정 클래스에 종속된다는 점이 다르다.
class Spreadsheet{
//지면상 코드 생략
protected:
static int sCounter = 0;
}
클래스 메서드 내에서 static 데이터 멤버 접근
메서드 안에서는 static 멤버를 일반 멤버 변수와 같은 방식으로 이용할 수 있다.
예를 들어 생성자 안에서 스프레드 시트 객체의 고유 순번 mId를 최종 순번을 담고있는 static 멤버 sCounter값으로 초기화 하고 싶다면,
class Spreadsheet{
public:
int getId() const'
protected:
static int sCounter = 0;
int mId;
};
Spreadsheet 객체의 고유 순번 할당 작업이 포함된 생성자를 다음과 같이 구현할 수 있다.
Spreadsheet::Spreadsheet(int inWidth, int inHeight):mWidth(inWidth), mHeight(inHeight)
{
mId = sCounter++;
mCells = new SpreadsheetCell* [mWidth];
for(int i=0; i<mWidth; i++){
mCells[i] = new SpreadsheetCell[mHeight];
}
}
//객체가 생성될 때 복제 생성자가 이용될 수도 있다는 것을 잊지말자
Spreadsheet::Spreadsheet(const Spreadsheet& src){
mId = sCounter++;
copyFrom(src);
}
//대입 연산자는 고유 순번 할당이 필요없다. 왜냐하면 고유 순번은 객체 생성 시점에 한번 할당된 후 변경되지 않아야한다.
클래스 메서드 밖에서의 static 멤버 접근
sCounter를 선언한 예제에서는 접근자로 protected를 사용했다. 이때문에 클래스 메서드 바깥에서는 sCounter 변수를 이용할 수 없다. 만약 public 으로 선언한다면 클래스 바깥에서도 접근할 수 있다. 클래스 밖에서 static 데이터 멤버에 접근하기 위해서는 스코프 지정 연산자를 다음과 같이 붙여주어야한다.
int c = Spreadsheet::sCounter;
하지만 클래스 데이터 멤버를 public으로 선언하여 외부에 노출하는 것은 바람직하지 않다.
public get/set 메서드를 통해 접근 권한을 얻도록하는 것이 좋다. static 멤버에 대한 get/set 메서드를 구현하려면 static method를 사용해야한다.
static 메서드
데이터 멤버의 경우와 마찬가지로 메서드도 특정 클래스의 모든 객체에 공통적으로 적용되야 할 때가 있다. static 메서드의 선언 방법은 static 데이터 멤버와 같다.
class SpreadsheetCell{
protected:
static string doubleToString(double val);
static double stringToDouble(const string& str);
}
static 메서드는 연결된 객체가 없으므로 코드 구현부에서 this 포인터를 이용할 수없다.
단, static 데이터 멤버들은 이용할 수 있다.
참고 : 전문가를 위한 C++
'C++ STL, 알고리즘' 카테고리의 다른 글
OOP (0) | 2024.10.02 |
---|---|
C++ 알쓸신잡 (0) | 2024.10.02 |
c++ 복습을 위한 링크 (0) | 2024.08.30 |
DP 다이나믹 프로그래밍 Dynamic Programming (0) | 2023.11.22 |
Greedy와 DP 알고리즘에 대한 고찰 (0) | 2023.11.22 |