C#

[C#] 구조체와 클래스의 차이

window= 2022. 9. 14. 23:06

▶ 구조체 

struct 구조체이름 
{
   //필드
   //메소드
}

▶ 구조체 선언 

struct MyStruct
{
   public int MyField1;
   public int MyField2;
   
   public void MyMethod()
   {
      //...
   }
}

★ 객체지향의 은닉성을 생각하면 필드는 private으로 선언되어야 좋은데 구조체에서 필드를 public으로 선언한 이유?

     ☞ 클래스는 객체를 추상화하려는데 존재의 이유가 있지만, 구조체는 데이터를 담기 위한 자료구조로 사용된다. 

         따라서 굳이 은닉성을 비롯한 객체지향의 원칙을 구조체에 강하게 적용하지 않는 편이며,

         편의를 위해 필드를 public으로 선언해서 사용하는 경우가 많다. 


클래스 VS 구조체 

특징 클래스 구조체
키워드 class struct
형식 참조 형식(힙에 할당) 값 형식(스택에 할당)
복사 얕은 복사 깊은 복사
인스턴스 생성 new 연산자와 생성자 필요 선언만으로도 생성
생성자 매개변수 없는 생성자 선언 가능 매개변수 없는 생성자 선언 불가능
상속 가능 불가능

 

  구조체  

▷ 구조체의 인스턴스는 스택에 할당되고 인스턴스가 선언된 블록이 끝나는 지점의 메모리에서 사라진다. 

 인스턴스의 사용이 끝나면 즉시 메모리에서 제거된다는 점과 가비지 콜렉터를 덜 귀찮게 한다는 점에서 구조체는 클래스에 비해 성능의 이점을 가진다. 

 구조체는 생성자를 호출할 때가 아니면 굳이 new 연산자를 사용하지 않아도 인스턴스를 만들 수 있다. 

 구조체는 값 형식이기 때문에 할당 연산자(=)를 통해 모든 필드가 그대로 복사된다. 

 

using System;

namespace Structure
{
   struct Point3D
   {
      public int X;
      public int Y; 
      public int Z;
      
      public Point3D(int X, int Y, int Z)
      {
         this.X = X; 
         this.Y = Y; 
         this.Z = Z;
      }
      
      public override string ToString()
      {
         return string.Format($"{X}, {Y}, {Z}");
      }
   }
   
   class MainApp
   {
      static void Main(string[] args)
      {
         Point3D p3d1;   //선언만으로 인스턴스가 생성.
         p3d1.X = 10;
         p3d1.Y = 20;
         p3d1.Z = 40;
         
         Console.WriteLine(p3d1.ToString());
         
         //생성자를 이용한 인스턴스 생성도 가능.단, 매개변수가 없는 생성자는 선언할 수 없음.
         Point3D p3d2 = new Point3D(100, 200, 300);
         
         //구조체의 인스턴스를 다른 인스턴스에 할당하면 깊은 복사가 이루어짐.
         Point3D p3d3 = p3d2;
         
         p3d3.Z = 400; 
         
         Console.WriteLine(p3d2.ToString());
         Console.WriteLine(p3d3.ToString());
      }
   }

 

변경 불가능 객체?

▷ 변경 불가능 객체의 효용은 여러 가지가 있지만, 멀티 쓰레드 간에 동기화를 할 필요가 없기 때문에 프로그램 성능 향상이 가능하고, 무엇보다 버그로 인한 데이터의 오염을 막을 수 있다. 

 구조체는 모든 필드와 프로퍼티의 값을 수정할 수 없는, 즉 변경 불가능 구조체로 선언할 수 있다. (클래스는 변경 불가능으로 선언할 수 없다. )

      ☞ readonly

          readonly를 이용해서 구조체를 선언하면, 컴파일러는 해당 구조체의 모든 필드가 readonly로 선언되도록 강제한다. 

          readonly로 선언된 구조체 안에서 readonly로 선언되지 않은 필드와 프로퍼티는 컴파일 에러를 일으킨다. 

          읽기 전용이므로 선언된 필드를 수정하려는 시도 또한 컴파일 에러가 발생한다. 

 

 

readonly struct ImmutableStruct
{
   public readonly int ImmutableField;
   publci ImmutableStruct(int initValue)
   {
      immutableField = initValue; //생성자에서만 초기화 가능. 
   }
}

class SomeClass
{
   public void SomeMethod()
   {
      ImmutableStruct is = new ImmutableStruct(123);
      is.ImmutableField = 456; //컴파일 에러. 
   }
}
반응형