아래의 내용을 이해하기 위해서는 메모리의 구조에 대해 알고있어야 한다.
객체지향의 클래스와 객체 그리고 인스턴스
객체(object)
실생활에서 우리가 인식할 수 있는 사물, 속성과 기능을 갖는 프로그램의 단위
객체지향 프로그래밍(OOP, Object-Oriented Programming)
객체의 속성과 기능을 구체화하는 형태의 프로그래밍
모든 데이터를 객체(object)로 취급한다.
클래스(Class)
객체 지향 프로그래밍에서 유사한 속성(attribute)과 메소드(method)를 공유하는 객체의 집합
간단히, 객체를 만들기 위한 설계도
인스턴스 (Instance)
하나의 클래스에서 생성된 객체
추상적인 개념인 클래스에서 실제 객체를 생성하는 것을 인스턴스화(instantiation)라고 한다.
클래스의 메모리 할당
C#에서 클래스를 생성할 때는, 해당 클래스 타입의 변수를 선언하고 new 키워드로 인스턴스를 생성하여 넣어준다.
여기서 선언한 변수는 할당된 메모리 주소를 가르키는 참조(포인트) 변수이다.
그리고 인스턴스를 생성하여 넣어주는 것은 해당 변수에 인스턴스의 주소값을 저장하는 것이다.
즉, 스택 영역의 변수에 new 키워드로 힙 영역에 할당한 인스턴스의 '주소'를 저장하는 것이다.
class Class
{
public int num;
}
class Program
{
static void Main(string[] args)
{
Class class1; // 주소 값을 저장할 참조 변수 선언
class1 = new Class(); // 인스턴스를 생성하여 인스턴스 주소 값을 변수에 저장
class1.num = 1;
}
}
위 소스의 경우, 아래의 형태로 클래스가 메모리에 할당된다.
C#에서 이러한 방식을 사용하는 이유는 스택 영역의 용량이 작기 때문이다.
C와 C++에서는 원시 타입처럼 new를 사용하지 않고 스택 영역에 인스턴스를 선언할 수 있다.
하지만 스택 영역은 용량이 고정되어 있고 보통 1MB 정도로 작은 편이다.
스택에 할당된 메모리를 모두 사용하면 스택 오버플로우가 발생하게 된다.
그렇다고 스택 영역의 용량을 높이면 스택 알고리즘의 구조 상 프로그램이 느려진다. (push, pop)
이에 반해 힙 영역은 스택 영역처럼 고정된 자료 구조가 아니기 때문에 용량이 크다.
하지만 이를 참조하기 위해서는 반드시 주소 값이 필요하기 때문에 이를 스택 영역에 보관하는 것이다.
주의할 점
class Class
{
public int num;
}
class Program
{
static void Main(string[] args)
{
Class class1;
class1 = new Class();
class1.num = 1;
Class class2 = class1;
class2.num = 2;
cout << class1.num << endl; // 2
cout << class2.num << endl; // 2
}
}
위 코드에서는 새로 선언한 클래스 변수 class2에 기존에 이미 할당된 클래스 변수 class1를 넣었다.
이 경우, class2의 멤버 변수인 num을 수정하면 class1과 class2의 num이 모두 변경된다.
이는 class1과 class2가 참조 변수로 힙 영역의 같은 클래스의 주소를 가지고 있기 때문이다.
위 소스의 경우, 최종적으로 이러한 메모리 형태가 될 것이다.
'개념' 카테고리의 다른 글
[C++] 참조자 개념 (2) const 참조자와 참조형을 반환하는 함수 (3) | 2022.09.30 |
---|---|
[개념] 메모리의 구조 (0) | 2022.09.20 |
[C++] 참조자 개념 (1) 참조자와 Call-by-reference (0) | 2022.09.20 |
[개념] 구조체 패딩 (Struct Padding) (1) | 2022.04.15 |
[개념] 빅 엔디안 & 리틀 엔디안 (Big-Endian & Little-Endian) (0) | 2022.03.28 |
댓글