Program Language/C & C++

[C++] 클래스 static 멤버

야곰야곰+책벌레 2022. 1. 14. 14:18
728x90
반응형

공개적으로 액세스 할 수 있는 전역 변수를 사용하지 않고도 편리함을 얻을 수 있다. 클래스의 일부이지만 해당 클래스의 객체의 일부가 아닌 변수를 static 멤버라고 한다. 일반 non-static 멤버와 같이 객체 하나의 복사본이 아니라 정확히 하나의 static 멤버 복사본이 있다. 마찬가지로 클래스의 멤버에 액세스해야 하지만 특정 객체에 대해 호출할 필요가 없는 함수를 static 멤버 함수라고 한다.

다음은 전역에 대한 의존으로 인한 문제없이 Date에 대한 기본 생성자 값의 의미 체계를 유지하는 설계다.

class Date {
	int d, m, y;
	static Date default_date;
public:
	Date(int dd =0, int mm =0, int yy =0);
	// ...
	static void set_default(int dd, int mm, int yy); // set default_date to Date(dd,mm,yy)
};

이제 다음과 같이 default_date를 사용하도록 Date 생성자를 정의할 수 있다.

Date::Date(int dd, int mm, int yy)
{
	d = dd ? dd : default_date .d;
	m = mm ? mm : default_date .m;
	y = yy ? yy : default_date .y;
	// ... check that the Date is valid ...
}

set_default()를 사용하여 적절한 경우 기본 날짜를 변경할 수 있다. static 멤버는 다른 멤버처럼 참조할 수 있다. 또한 객체를 언급하지 않고 static 멤버를 참조할 수 있다. 대신 해당 이름은 클래스 이름으로 한정된다.

void f()
{
	Date::set_default(4,5,1945); // call Date’s static member set_default()
}

사용되는 static 멤버(함수 또는 데이터 멤버)는 어딘가에 정의되어야 한다. 정적 멤버의 정의에서 static 키워드는 반복되지 않는다.

Date Date::default_date {16,12,1770}; // definition of Date::default_date
void Date::set_default(int d, int m, int y) // definition of Date::set_default
{
	default_date = {d,m,y}; // assign new value to default_date
}

이제 기본값은 누군가가 달리 결정할 때까지 유지된다.

Date {}는 Date::default_date 값에 대한 표기법으로 사용된다.

Date copy_of_default_date = Date{};

void f(Date);

void g()
{
	f(Date{});
}

따라서 기본 날짜를 읽기 위한 별도의 함수가 필요하지 않는다. 또한 대상 유형이 분명히 Date인 경우 일반 {}이면 충분하다.

void f1(Date);
void f2(Date);
void f2(int);
void g()
{
	f1({}); // OK: equivalent to f1(Date{})
	f2({}): // error : ambiguous: f2(int) or f2(Date)?
	f2(Date{}); // OK
}

다음 스레드 코드에서 static 데이터 멤버는 경쟁 조건을 피하기 위해 일종의 잠금 또는 액세스 규칙이 필요하다. 

728x90
반응형