BASHA TECH

c++ 생명주기 본문

Computer/C++

c++ 생명주기

Basha 2023. 2. 15. 22:22
728x90
// lifetime.cpp : lifetime and location
// (2) C++ 오브젝트의 존속기간(lifetime)과 저장부류(storage class) 관점에서 프로그램을 기술하세요.
// 프로그램 내의 심볼은 자신이 생성되는 시점과 소멸되는 시점. 즉, 존속기간을 가진다. 
// 심볼이 생성된다는 것은 프로그램이 실행되어  메모리 공간을 할당 받는 것을 의미하고 소멸된다는 것은 공간을 반환하는 것이다.
// 객체 존속 기간을 다양하게 지정할 수 있다는 것이다. 
// 즉 프로그램의 실해왁 같은 존속 기간을 주어 실행 중 필요한 때에 언제라도 그 객체를 접근하게 할 것인지(정적 존속기간) 아니며 계산의 중간 결과를 위해 임시 객체를 둘 것인지(지역 존속기간), 또는 객체의 생성과 소멸을 프로그래머가 제어할 것인지(동적 존속기간)를 결정해야한다.
#include <iostream>

using namespace std;

class C {

	int id;

public:

	C(int i); // 생성자
	~C(); // 소멸자
};

// 생성자 정의
C::C(int i)
{
	id = i;
	cout << "객체(" << id << ") 생성\n";
}
// 소멸자 정의
C::~C()
{
	cout << "객체(" << id << ") 소멸\n";
}

// gobj(1)은 전역 객체이므로 실행 프로그램이 시작될 때 데이터 영역에 잡혀서 프로그램이 실행되는 동안 계속 있다가 프로그램이 끝날 때 같이 사라진다.
// 프로그램의 실행과 같은 정적 존속 기간을 갖는다. 전역 객체를 생성할 때 불리는 생성자가 먼저 후생 되고 main 함수에 진입한다. 
// 즉, 이 객체는 가장 먼저 생성되고 가장 나중에 소멸한다.
C gobj(1);	// 전역 객체

void f()
{
	cout << "	함수 f() 시작\n";
	static C sobj(2); 	// 정적 객체 : 정적 존속 기간을 갖는다.	
	// 정적 존속 객체는 함수 f()에 진입하고 나서야 생성자가 호출된다. 범위와 존속기간의 개념이 다르기 때문이다.
	// 범위는 이 함수에 블록에만 국한 되는 지역 범위를 가지는 반명존속기간은 프로그램의 실행과 동일한 정적 존속기간을 갖기 때문.
	// 이 정적 객체는 프로그램이 시작될 때 전역 객체와 같이 객체의 크기 만큼 데이터 영역에 잡힌다. 그리고 함수 f()를 시작할 때 비로소 범위가 잡히기 때문에 그 때 생성자를 호출해서 멤버를 초기화한다.
	// 따라서, 이 객체는 함수 블록이 끝나도 곧바로 소멸되지 않고 프로그램이 종료될 때 (main 함수 블록이 종료될 때) 전역 객체와 함께 소멸된다.
	C fobj(3);
	cout << "	&sobj = " << (unsigned long)(&sobj) << endl;
	cout << "	&fobj = " << (unsigned long)(&fobj) << endl;
	cout << "	함수 f() 끝\n";
 }

// main()함수 내의 지역 객체 mobj(4)와 함수 f()의 지역 객체 fobj(3)은 지역 존속기간을 가진다.
// 이 지역 객체는 함수가 선언될 때 생성되었다가 함수가 끝나면 함께 소멸된다.
void main()
{
	cout << "	함수 main() 시작\n";
	C mobj(4);
	C *pobj = new C(5);
	// main()함수의 주소를 얻고 있다. 
	// %main은 main()함수에 대한 주소를 나타내며 (unsigned long)(&main)은 이 주소를 unsigned long 타입으로 형변환을 시켜준다. 
	// 포인터 타입의 크기는 워드 크기이고 주소 공간은 양수이므로, unsigned long형으로 명시적 변환을 시켰다. 
	// main()함수의 주소를 T라고 했을 때, T는 프로세스 모델 중에서 텍스트 영역의 주소 공간에 해당한다. 
	// 이 T값에 비교해서 함수 f()는 상대적으로 main()함수와 가까운 위치에 있다.
	// 함수 f()도 텍스트 영역, 실행 코드가 들어 있는 영역에 속하게 된다.
	cout << "	&main = " << (unsigned long)(&main) << endl; 
	cout << "	&f    = " << (unsigned long)(&f) << endl;
	// 전역 객체 gobj에 대한 주소를 얻고 있다. 이 주소를 D라 했을 때 D는 프로세스 모델 중에서 데이터 영역의 주소 공간에 해당한다.
	// 결과를 보면 D는 T에 비해 상대적으로 높은 주소에 있음을 볼 수 있다. 데이터 영역에 잡히는 또 하나의 정적 객체 sobj는 D에 가깝게 위치하고 있다.
	// 스택에 잡히는 자동 변수나 자동 객체에는 main()함수 블록 안의 지역 객체 mobj와 포인터 변수 pobj, 그리고 함수 f()안의 지역 객체 fobj가 있다. 
	// 각각의 스택에서의 상대적인 위치는 컴파일러가 결정한다.
	// 유일하게 자유 공간 영역, 즉 힙에 잡히는 객체 5의 주소는 포인터 변수 pobj가 가지고 있다.
	// 그 주소 값은 windows 환경에서는 오히려 더 큰 값으로 나왔다. 이것은 원거리 힙에 할당 했기 때문이다.
	// 원거리 힙은 개념적으로 스택 상단의 자유 공간 영역이다. 다른 컴파일러와 다른 환경에서는 다른 결과가 나 올 수 있다.
	cout << "	&gobj = " << (unsigned long)(&gobj) << endl;
	cout << "	&mobj = " << (unsigned long)(&mobj) << endl;
	cout << "	&pobj = " << (unsigned long)(&pobj) << endl;
	cout << "	pobj  = " << (unsigned long)(pobj) << endl;
	f();
	delete pobj;
	cout << "	함수 main() 끝\n";
}
728x90
반응형

'Computer > C++' 카테고리의 다른 글

file2.cpp - 정적 변수  (0) 2023.02.15
file1.cpp - 전역 변수, 정적 변수  (0) 2023.02.15
hello.cpp  (0) 2023.02.15
C++ tutorial  (0) 2023.02.07
Comments