[C#] 객체 생성 방법과 C++와 차이점 (+ reference)

인트로

C#은 C++와 객체 생성 방법이 다를까?
C#은 포인터가 없을까?

 

본 포스팅에선 C#에서 객체를 생성하는 방법과 C++와 차이점 그리고 레퍼런스에 대해 알아보려 한다.

객체 생성 코드

class Orange
{
    private int _price;

    public Orange(int price)
    {
        _price = price;
    }

    public int GetPrice()
    {
        return _price;
    }

    public void SetPrice(int price)
    {
        _price = price;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Orange orange = new Orange(100);
        Console.WriteLine($"오렌지 가격 : {orange.GetPrice()}");

        orange.SetPrice(500);
        Console.WriteLine($"오렌지 가격 : {orange.GetPrice()}");
    }
}

객체 생성 이해하기 C++ vs C#

Orange orange = new Orange(100);

 

C++는 객체를 스택 또는 힙에 할당하지만 C#은 객체를 힙에 할당한다.

C++와 또 다른 차이점은 new 키워드를 사용했음에도 변수 선언 시 * 키워드를 사용하지 않았다는 점이다.

 

어째서 C#은 객체 생성 방법이 C++와 다른 걸까?

 

결론부터 말하면 C#은 레퍼런스 타입이란 게 존재한다.

C#의 모든 클래스는 레퍼런스 타입이며 orange는 레퍼런스 변수로 실제 객체가 할당된 힙의 메모리를 참조하게 된다.

 

이렇게 보면 C++의 포인터와 동일한 것 같지만 전혀 다르다.

포인터가 고정적으로 메모리의 주소를 가리킨다면

레퍼런스도 메모리 주소를 가리키되 가비지 컬렉터에 의해 옮겨진 객체의 힙 주소가 자동으로 갱신되는 등 .NET에서 엄격하게 관리되는 안전이 보장된 메모리 참조 형태이다.

 

여담으로 Java도 C#과 매우 유사하게 포인터를 사용하지 않는데 이는 의도된 설계이며 포인터가 사용하기 까다롭고 오류가 발생하기 쉬운 구조이기 때문이다.

 

다시 본론으로 돌아와 정리하면 C#의 객체는 힙에 할당된다. 그리고 그 주소를 참조하는 변수는 레퍼런스 타입으로 포인터와 유사하지만 조금 더 세련되고 안전한 형태이다.