클래스 사용 도중 헷갈리던 내용이 있어서 정리함.
함수 내에서 임시로 객체를 생성할 때 사용 용도에 따라 비효율적인 부분이 있는지 헷갈려서 instance 생성 시 각 멤버들이 어떻게 메모리를 차지하는지 개념을 정리하기 위한 글.
우선 class는 멤버 변수와 멤버 함수를 가질 수 있고 각각 정적(static)과 비정적(non-static) 멤버 변수, 함수를 가질 수 있다.
먼저 클래스 타입의 객체 또는 인스턴스 자체의 크기는 비정적 멤버 변수만 영향을 미친다. 즉 멤버 변수로 int형 변수 1개를 가지면 이 클래스의 instance의 sizeof는 4바이트, 2개를 가지면 8바이트 이런 식. 비정적 멤버 변수는 객체의 생성과 동시에 생성된다. 객체 내의 지역 변수와 동일하므로 스택에 저장된다. (물론 동적으로 할당되는 메모리는 heap 영역에 저장됨)
또한 비정적 멤버 변수는 클래스 내에서 공유되는 변수가 아닌 하나의 객체마다 할당되는 변수이다.
만약 클래스 내에 정적 멤버 변수를 선언했다면 이 변수는 객체 생성 시 할당되는 것이 아니라 프로그램 시작 시 데이터 영역에 생성된다. 따라서 정적 멤버 변수는 객체의 크기에 영향을 미치지 않는다. int형 변수 2개와 static int형 변수 1개를 멤버로 가지는 클래스를 예로 들면, 프로그램 시작 시 static int 타입 변수가 하나 생성되며, 해당 객체를 생성할 때 int형 변수 2개를 가진 객체가 생성된다. 이 객체의 sizeof는 8바이트다. 정적 멤버 변수는 객체마다 할당되는 변수가 아니기 때문에 해당 클래스로 생성되는 모든 객체가 공유하는 1개의 변수이며 프로그램 시작 시 데이터 영역에 저장된다.
다음은 멤버 함수이다. 멤버 함수도 동일하게 정적과 비정적으로 나뉘며 멤버 함수는 정적, 비정적 모두 객체의 크기에 영향을 미치지 않는다. 멤버 함수는 모두 code 영역에 저장되며 멤버 함수는 객체마다 다르게 동작하는 것이 아니기 때문에 객체마다 함수가 할당되면 비효율적일 것이다. 따라서 해당 클래스의 모든 객체는 code 영역에 있는 멤버 함수를 공유하며 사용한다.
정적 멤버 함수는 객체 생성 시가 아닌 프로그램 시작 시 code 영역에 저장되기 때문에 객체를 생성하지 않아도 사용할 수 있어야 한다. 따라서 클래스의 이름을 통해 접근할 수 있으며, 당연히 객체의 이름을 통해서도 접근이 가능하다. 참고로 정적 멤버 함수에서 비정적 멤버 변수 또는 비정적 멤버 함수를 사용할 순 없다. 이는 메모리가 생성되는 순서를 생각해보면 당연한 일.
이제 간단한 클래스 또는 구조체를 통해 메모리 상에 어떻게 저장되는지 확인해보자.
다음 구조체는 4바이트 멤버 변수를 3개 가진다.
struct Foo
{
uint32_t mUnsignedInteger;
int32_t mSignedInteger;
float mFloatingPoint;
};
위 구조체의 객체는 다음과 같은 메모리 구조를 가진다.
기존 구조체에 static 멤버 변수를 추가하였다.
struct Foo
{
uint32_t mUnsignedInteger;
int32_t mSignedInteger;
float mFloatingPoint;
static uint32_t mStaticInteger;
};
하지만 위에서 말했듯이 정적 멤버 변수는 프로그램 시작 시 데이터 영역에 생성되기 때문에 객체의 메모리에 영향을 미치지 않는다. 따라서 동일한 메모리 구조를 가진다.
'C,C++ > C++' 카테고리의 다른 글
[C++] 복사 생성자 및 할당(=) 연산자가 호출되는 시점 | 초기화와 할당의 차이 | RVO(Return Value Optimization) (0) | 2020.02.07 |
---|---|
[C++] 캐스팅 연산자에 대해 알아보자 | static_cast, reinterpret_cast (0) | 2020.01.23 |
[C++] 조정자(Manipulator)를 알아보자 (0) | 2020.01.03 |
[C++] 가비지 컬렉션과 참조 카운트에 대해 알아보자 | 메모리 관리 자동화 (0) | 2019.12.30 |
[C++] C 스타일 enum과 C++ 11의 Enum class에 차이에 대해 알아보자 (0) | 2019.12.18 |
댓글