728x90

본 포스팅에서 다룰 내용은 static member function과 static member variable이다. 정적 멤버 함수와 정적 멤버 변수이다. 여기서 얘기하는 static은 static link와 별개의 내용이다. 

 

Static Member Function

 

static member variable은 정적 멤버 변수이다. 정적 멤버 함수란 오브젝트가 없이도 호출이 가능한 함수이다. 일반 멤버 함수의 경우는 오브젝트를 생성 후 해당 오브젝트가 가지고 있는 주소 값에 의존하여 멤버 함수를 호출하는 방식이다. 하지만 static member function은 아니다. 

#include <iostream>

class Dog
{
public:
	void spaek()
	{
		std::cout << "woof" << '\n';
	}
	static void staticSpeak()
	{
		std::cout << "WOOF!" << '\n';
		//std::cout << mAge << '\n';	불가능!
		//spaek(); 불가능!
	}
private:
	
	int mAge;
};


int main()
{
	Dog choco;

	choco.spaek();
	
	Dog::staticSpeak();		//객체
	choco.staticSpeak();	//오브젝트의 멤버 함수이기 때문에 call가능
}

위 코드에서 Dog라는 클래스에 static member function인 staticSpeak() 함수가 존재한다. 해당 함수는 main함수에서 객체를 생성하지 않고 바로 호출이 가능하다. Dog::staticSpeak()와 같은 형식으로 호출이 가능하다. 여기서 추가적으로 staticSpeak()는 클래스의 멤버 함수이기도 하기 때문에 오브젝트를 이용하여 호출 또한 가능하다. choco.staticSpeak();

 

static member function의 특징으론 해당 함수는 객체의 주소 값을 가지고 있지 않기 때문에 static member function내에서 멤버 변수 혹은 멤버 함수를 호출하는 것이 불가능하다. 왜냐하면 기본적으로 멤버 변수와 멤버 함수는 this초인터를 이용하여 호출이 진행이 되는데 위에 말했다시피 static member function은 해당 주소 값을 가지고 있지 않게 때문이다.

 

 

Static Member Variable

 

static member variable은 정적 멤버 변수이다. 해당 변수는 오브젝트 안에 존재하지 않고 static 메모리 영역에 존재하게 된다. 그 뜻은 하나의 변수를 공유하게 된다는 뜻이다. 

#include <iostream>

class Dog
{
public:
	static int count;
	void spaek()
	{
		++count;
		std::cout << "woof" << '\n';
		std::cout << "count : " << count << '\n';
	}
private:
	int mAge;
};

int Dog::count = 0;

int main()
{
	Dog choco;
	Dog mong;

	choco.spaek();
	mong.spaek();
	
}

 

클래스를 먼저 보면 static int count static member variable이 public에 선언이 되어있다. static member variable은 프로그램이 실행되기 전에 초기화가 이루어져야 한다. main함수에서 두 객체 choco와 mong의 멤버 함수 speak() 호출을 통해 count를 증가시키고 count를 출력한 결과 mong.spaek()에서 count가 2가 된 것을 확인할 수 있었다. 그 이유는 아까 설명한 대로 static 메모리에 저장이 되어 객체 간 하나의 변수를 공유하기 때문이다. 

 

위 코드에서 문제가 될 수 있는 점이 있다. 바로 static member variable이 public에 선언이 되었기 때문에 객체를 이용해서 해당 변수를 manipulate 할 수 있다는 점이 문제가 될 수 있다. 이 점을 해결하기 위해 private에 옮겨 문제를 해결하는 방법이 있지만 더 나은 해결 방안은 현재 코드에서 해당 변수를 speak() 멤버 함수에서만 사용이 되기 때문에 speak() 멤버 함수 안에 선언하는 방법 또한 안전한 방법이다. 

#include <iostream>

class Dog
{
public:
	void spaek()
	{
		static int count = 0;		//컴파일할때 한번 선언됨.
		++count;
		std::cout << "woof" << '\n';
		std::cout << "count : " << count << '\n';
	}
private:
	int mAge;
};


int main()
{
	Dog choco;
	Dog mong;

	choco.spaek();
	mong.spaek();
}

처음에 speak() 안에 선언하면 선언할떄마다 해당 정적 멤버 변수가 새로 선언이 되는 것이 아닌가라는 생각을 하게 되었는데 잘 생각해보니 해당 변수는 컴파일 타임에 선언이 되기 때문에 런타임에는 해당 선언을 무시하게 된다. 

 

 

Ref.

https://www.youtube.com/watch?v=oD6fKjyX5to&t=242s

+ Recent posts