C++문법 공부

정적 맴버 함수를 사용해서 객체를 생성하기

막뇌 2023. 6. 22. 16:32

정적 맴버 static 함수와 변수를 활용하는 예제를 만들어 보았습니다.

#include <iostream>
#include <string>
using namespace std;

//Movie Class
class Movie
{
public:
	string name;	//영화 이름
	int year;	//출시 년도
	int number;	//영화 넘버

	void Print();
	void ShowNumber();

private:
	//생성자
	Movie(const string& name_arg, const int& year_arg, int movieNumber_arg);

public:
	//정적 맴버
	static int movieNumber;
	static Movie* CreateMovie(const string&, const int& year_arg);
};

int Movie::movieNumber = 0;

Movie* Movie::CreateMovie(const string& name_arg, const int& year_arg)
{
	//영화 객체를 생성한다.
	Movie* p = new Movie(name_arg, year_arg, Movie::movieNumber++);
	//새로 생성된 영화 객체를 반환
	return p;
}

Movie::Movie(const string& name_arg, const int& year_arg, int movieNumber_arg)
{
	name = name_arg;
	year = year_arg;
	number = ++movieNumber_arg;
}

void Movie::Print()
{
	cout << "{Name = " << name << ", Mv.Year = " << year << ", Mv. Num. = " << number << "}\n";
}
void Movie::ShowNumber()
{
	cout << "입력된 영화의 수는 " << movieNumber << "개 입니다." << endl;
}

int main()
{
	//영화 객체를 세 개 생성한다.
	Movie* p1, * p2, * p3;
	p1 = Movie::CreateMovie("블랙호크다운", 2001);
	p2 = Movie::CreateMovie("밴드 오브 브라더스", 2001);
	p3 = Movie::CreateMovie("더 퍼시픽", 2010);

	p1->Print();
	p2->Print();
	p3->Print();

	p3->ShowNumber();
	

	//객체들을 동적으로 생성했으므로 해제해줄 필요가 있다.
	delete p1;
	delete p2;
	delete p3;
	p1 = p2 = p3 = 0;

	return 0;
}

 

Movie 클래스에 맴버를 설정합니다.

name  = 영화이름

year = 영화의 개봉년도

number = Key값으로 쓰일 숫자가 되겠습니다.

Print 함수와 ShowNumber 함수는 출력과 지금 몇개까지 영화가 쌓여있는지 알려주는 함수입니다.

 

 

특이한점이 private 접근지정자로 생성자를 처리함으로서 생성자에 접근할 수 있는것은 맴버 뿐입니다.

그 맴버가 CreateMovie 함수이고, static 으로 선언되어있습니다.

정의 부로 들어가면 받은 매개변수를 바탕으로 생성자를 핸들하고 있습니다.

생성자에 들어가는 매개변수는 Movie::movieNumber로 class 외부에서 함수를 정의하고 있기 때문에 스코프 연산자를 사용해서 Movie class 맴버임을 확인해줍니다.

CreateMovie 함수는 인자 2개를 받지만 static 변수를 활용해서 생성자에게는 인자3개를 주고 있네요.

스코프 연산자 다음에는 전위연산자를 사용할 수 없기 때문에 다른 방법을 고려 해야 하는데요

저는 생성자 안쪽에서 맴버변수 number에 대입하는 과정에서 전위연산을 처리 하는 것으로 해결 했습니다.

주의깊게 볼 점은 movieNumber 의 레퍼런스를 매개변수로 받는 것이 아니었기 때문에

생성자 구현 코드 안쪽에서 movieNumber_arg에 전위연산을 하지만 실제 Movie::movieNumber가 영향을 받지는 않습니다.

레퍼런스를 쓰지 않으면 아무리 함수안에서 매개변수를 건드려도 함수가 끝나는 순간 끝이라는 것을 보여주죠.

 

이 예제 코드를 직접 만들어 보면서 static 맴버 변수와 함수를 어떻게 선언하고 사용하게 되는지 간단하 알게 되었습니다.

static 맴버 변수에는 맴버 모두가 접근할 수가 있으며 그 값을 공유하는 특징이 있고

static 맴버 함수도 '맴버'이기 때문에 생성자가 private 인 경우에도 생성자에 접근하여 객체를 생성할 수 있습니다.

 

이렇게 코드를 만들면 객체를 할당하기 위해 반드시 동적할당을 사용할 수 밖에 없게 됩니다.

정적 맴버 함수 안에서 일반 객체를 정의하면 함수가 종료되면서 일반 객체가 메모리에 남지 않고 사라지기 때문이다.

또한 생성자가 private 이기 때문에 일반적인 방법으로는 객체를 생성하는것이 불가능 하다.

Movie* Movie::CreateMovie(const string& name_arg, const int& year_arg)
{
	Movie newP("해바라기", 2006, Movie::movieNumber++);
	//영화 객체를 생성한다.
	Movie* p = new Movie(name_arg, year_arg, Movie::movieNumber++);
	//새로 생성된 영화 객체를 반환
	return p;
}

(여기서 생성된 newP는 함수 호출이 끝나면 사라진다.)

정적 맴버 함수로 객체 생성(동적 할당)에 대해 예제를 직접 만들면서 실습 해 보았다.