비트를 쪼개는 개발자

allen321@naver.com

C#

C# - Struct 와 Class의 차이점

MozarTnT 2024. 6. 21. 19:22
728x90
반응형

 

 

 

 

구조체란?

 

 

우선 프로그래밍 언어에서는 변수를 선언할때 이 변수를 담아두는 그릇인 자료형을 먼저 선언하게 된다.

 

이 변수들을 한 곳에 모아놓고 싶을 때 같은 자료형의 변수라면 배열로 선언할 수 있겠지만 나중에 해당 변수들을 쉽게 가져오거나 혹시나 다른 자료형을 가진 변수들도 모아 놓고 싶다면 코드 관리가 점점 어려워진다.

 

 

 

 

구조체는 이러한 점을 해결하기 위해 초기 기존의 C 언어에서 만들어진 기능이다.

 

구조체는 데이터, 즉 하나 이상의 변수들을 모아놓고 새로운 자료형을 정의하는 도구로써 작동한다.

 

 

키워드로는 struct를 사용하여 선언해주며 내부에는 원하는 자료형을 자유롭게 사용하여 선언해 주면 된다.

 

 

 

struct의 데이터는 값 타입(call by Value)으로 저장되며 스택 메모리에 할당된다. 

 

 

 

예시 코드로 살펴보자

 struct ExamScore
 {
     public int koreanScore;
     public int mathScore;
     public int englishScore;
     public int scienceScore;

     public void ShowTotalScore()
     {
         int totalScore = this.koreanScore + this.mathScore + this.englishScore + this.scienceScore;
         Console.WriteLine($"Total Score is {totalScore}");
     }
 }

 

 

성적을 담은 struct를 선언해주고 성적을 합산한 결과값을 출력해주는 함수도 선언해주자.

 

해당 구조체를 main문에서 선언하면 이렇게 된다.

 

 

 static void Main()
 {
     ExamScore tomScore = new ExamScore();

     tomScore.koreanScore = 98;
     tomScore.mathScore = 95;
     tomScore.englishScore = 93;
     tomScore.scienceScore = 100;

     tomScore.ShowTotalScore();
 }

 

 

main문에서는 tom이라는 친구의 성적을 하나 선언해주고 tomScroe에 해당하는 변수들의 값을 선언하자

 

 

 

 

 

 

 

Class(클래스)

 

 

 

클래스는 초기의 c언어에 객체 지향 프로그래밍 개념을 추가한 c++로 넘어가면서 널리 쓰이게 된 객체 지향 프로그래밍의 핵심 개념이다. 

 

 

클래스 역시 구조체(struct) 와 비슷하게 여러 데이터(변수)들과 함수들을 묶어서 하나로 추상화 시킬수 있으며 사용 방법은 struct와 비슷한 편이다. 다만 데이터를 참조 타입(call by Reference)으로 저장하며 힙 메모리에 할당시킨다.

 

 

하지만 struct와 클래스는 여러 면에서 다른점이 많은데 자세한 차이점은 아래에서 따로 언급하겠다.

 

 

 

 

우선 클래스를 선언하는 방법은 다음과 같다.

 

 

 

  class ExamScoreClass
  {
    // 속성
      public int koreanScore;
      public int mathScore;
      public int englishScore;
      public int scienceScore;

      public ExamScoreClass(int koreanScore, int mathScore, int englishScore, int scienceScore) // 생성자
      {
          this.koreanScore = koreanScore;
          this.mathScore = mathScore;
          this.englishScore = englishScore;
          this.scienceScore = scienceScore;
      }

      public void ShowTotalScore()
      {
          int totalScore = koreanScore + mathScore + englishScore + scienceScore;
          Console.WriteLine($"Total Score is {totalScore}");
      }
  }

 

 

struct와 비슷한 기능을 하는 class를 만들어보자

 

 

ExamScore를 담당하는 class를 선언하고 생성자를 선언해준다.

 

 

소멸자의 경우 C# 언어의 경우에서는 가비지 컬렉터가 자동으로 동작하여 메모리를 관리하기 때문에 특정 리소스를 특정 시점에 꼭 소멸시키는 경우가 아니라면 기입하지 않아도 class에 할당된 메모리는 자동으로 해제된다.

 

 

 

 

 

 

 

 

Struct와 Class의 차이점

 

 

 

 

원하는 사용자 지정 데이터 타입을 지정한다는 면에서 Struct와 Class는 비슷하지만 사실 그 이상으로 많은 차이점이 존재한다. 차이점을 잘 파악하고 사용해야 효율적인 코드 구조를 만들 수 있다.

 

 

1. 데이터 참조 형식

 

  • Struct는 데이터를 값 형식(Value Type)으로 Stack 메모리에 할당시킨다.
  • Class는 데이터를 참조 형식(Reference Type)으로 Heap 메모리에 할당시킨다. (가비지 컬렉션)

 

 

2. 상속

 

  • Struct는 상속을 지원하지 않는다.
  • Class는 상속을 지원하기 때문에 다른 클래스에서 파생되어 상속 계층 구도를 만들 수 있고 이는 객체 지향 프로그래밍의 특징인 상속의 중요한 예시중 하나이다.

 

 

 

3. 데이터의 불변성

 

  • Struct 내부 데이터의 특정 값을 직접 세팅할 수 없다, 따라서 변경이 가능한 구조체를 만드는것은 구조체에 어울리지 않는다.
  • Class 내부 데이터의 특정 값을 세팅해 줄 수 있고 변경이 가능하다.

 

 

4. 성능

 

  • Struct는 값 형식으로 스택 메모리에서 데이터를 가져오기 때문에 메모리 할당과 해제가 Class보다 빠를 수 있다.
  • 구조체의 크기가 작을 수록 성능면에서 유리하다.
  • Class는 메모리 할당과 헤제가 느릴 수 있지만 대규모거나 복잡한 데이터를 조작할 때 더 효율적일 수 있다.

 

 

 

 

Struct를 사용하는 곳

 

 

대부분의 객체 지향 프로그래밍에서는 사용자 지정 데이터 타입을 지정해야 하는 경우 Class를 압도적으로 많이 사용하게 된다. 

 

MS 공식 문서에서는 Struct의 경우 다음과 같은 경우에 사용하는 것을 권장하고 있다.

 

 

 

출처 : https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct?WT.mc_id=DT-MVP-4038148

 

Choosing Between Class and Struct - Framework Design Guidelines

Learn how to decide whether to design a type as a class, or to design a type as a struct. Understand how reference types and value types differ in .NET.

learn.microsoft.com

 

 

 

 

해석하자면 구조체의 경우는 아래의 네개의 경우를 충족할 때만 사용하라고 권장한다.

 

  • 논리적으로 단일 값을 가지며 기본 타입으로 정의해야 할 경우(int나 double과 같은)
  • 인스턴스 크기를 16바이트 미만으로 가질 경우
  • 데이터가 불변일 경우
  • 박싱이 자주 일어나지 않는 경우

 

 

 

반복문 내부에서 임시객체와 같은 경우에 struct를 사용하기 좋은데 여기서 class를 사용하게 되면 상당한 빈도로 heap 메모리에 할당과 해제를 반복한다.

이 많은 경우에 가비지 컬렉션이 계속해서 동작하게 되는것은 시스템이 효율적으로 작동한다고 볼 수 없다.

 

다만 값을 호출하는 과정에서 class와 struct는 데이터를 참조하는 방식이 다르기 때문에 이 부분은 상황에 알맞게 수정하는 편이 바람직하다.

728x90
반응형