포스트

[static 키워드] 03_정적 멤버 함수

static 멤버 함수클래스의 인스턴스 없이 호출될 수 있는 함수로, static 멤버 변수처럼 공유 메모리 공간에 존재합니다.

따라서 객체 이름 뿐만 아니라 클래스 이름으로도 접근 가능하며, 객체와 독립적으로 존재합니다.

객체와 독립적으로 존재하기 때문에 공유 메모리에 존재하는 정적 멤버 변수가 아닌 객체가 각자 소유하고 있는 일반 멤버 변수는 사용할 수 없습니다.

같은 이유로, 정적 멤버 함수가 호출 될 때, 일반 멤버 함수들이 가지는 this 포인터가 없습니다.

this 포인터객체 자기 자신의 주소를 가리키는 포인터입니다.
즉, 객체가 생성되어야 자기 자신을 가리킬 수 있는데, 정적 멤버 함수객체들의 생성과 상관 없이 언제 어디서든 호출할 수 있는 함수입니다.
따라서 정적 멤버 함수는 this 포인터를 사용할 수 없습니다.
그리고 이 때문에 객체가 생성되어야 함께 생성되는 비정적 멤버 변수들 또한 사용할 수 없습니다.
(비정적 멤버 변수의 접근도 this-> 로 접근합니다.)

또한, 정적 멤버 함수는 가상(virtual)이 될 수 없습니다.

정리

  • 객체의 이름이나 클래스의 이름으로 호출 가능
  • this 포인터가 없음
  • 일반 멤버 변수를 사용할 수 없음
  • virtual이 될 수 없음


1
2
3
4
5
6
7
8
9
10
11
12
#pragma once
class Test
{
public:
	static int a;

public:
	static void func()
	{
		a = 10;
	}
};

객체와 정적 멤버 함수

static 멤버 함수를 사용하는 이유

그렇다면, this 포인터도 없고, 일반 멤버 변수도 사용할 수 없는 정적 멤버 함수를 쓰는 이유가 뭘까?

1. 객체와 무관한 호출

일단, 객체와 무관하게 클래스의 함수를 호출하고 싶을 때 사용합니다.

나중에 싱글톤이라는 디자인 패턴을 배우게 된다면 이유를 알 수 있겠지만, 객체 생성 여부와 상관 없이 호출해야 하는 함수를 디자인 할 때 사용합니다.

2. private인 static 멤버 변수 사용

위에서 한 번 언급했지만, static 멤버 함수는 일반 멤버 변수에 접근할 수 없지만 static 멤버 변수에 접근 가능합니다.

이때, 정적 멤버 변수를 private로 만들고 싶다면 이를 호출하는 방법으로 정적 멤버 함수를 이용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

class Test
{
private:
	static int b;

public:
	static void func()
	{
		b = 20;
	}

	static int getB() { return b; }
};

int Test::b = 1;

int main()
{
	//Test::b; //접근 불가
	Test::func();

	cout << Test::getB();
}

참고

지역 변수, 전역 변수, 정적 변수, 동적 변수

외부 변수와 extern, 그리고 외부 링크

[static 키워드] 01_전역 정적 변수와 지역 정적 변수

[static 키워드] 02_정적 멤버 변수

이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.