2024. 11. 6. 15:30ㆍSTUDY/C#에 대한 다양한 공부
[Class vs Struct]
기본 개념
class | struct |
참조 타입으로 힙(heap) 메모리에 할당된다. 객체의 참조를 다루므로, 객체를 여러 변수가 공유할 수 있다. C#에서 class는 객체 지향 프로그래밍의 기본 단위로 많이 사용된다. |
값 타입으로, 주로 스택 메모리에 할당된다. 값 자체를 복사하여 다루므로, struct 변수를 다른 변수에 할당할 때, 별도의 독립된 복사본이 생성된다. C#에서는 작은 데이터 묶음이나 단일 데이터 처리에 주로 사용된다. |
메모리 할당 방식
class | struct |
힙 메모리에 할당되며, 변수가 객체의 메모리 위치를 참조한다. 가비지 컬렉터가 사용되지 않는 객체를 자동으로 해제한다. 크기가 큰 데이터를 다루기에 적합하다. |
주로 스택에 할당되며, 변수에 실제 데이터 값이 저장된다. 스택에서 바로 메모리 해제되므로 관리가 용이하지만, 크기가 큰 struct는 성능에 부담을 준다. 작은 크기의 간단한 데이터 구조에 적합하다. |
복사 방식
class | struct |
참조에 의한 복사로, 같은 객체를 여러 변수가 참조할 수 있다. 하나의 변수가 데이터를 변경하면 참조 중인 다른 변수들도 영향을 받는다. |
값에 의한 복사로, 새로운 복사본이 생성된다. 다른 변수에 영향을 미치지 않으며, 독립적인 값으로 사용하여 원본 데이터 보호에 강점을 가진다. |
상속과 다향성
class | struct |
클래스간 상속이 가능하며, 다향성을 지원한다. 기본적으로 객체 주요 개념인 캡슐화, 상속, 다향성을 지원한다. |
상속이 불가능하며, 다른 struct를 상속할 수 없다. |
struct를 설명할때 왜 '주로' 스택에 할당된다고 하였는가?
참조 타입은 기본적으로 heap, 값 타입은 stack에 저장된다는 점을 기억하자. (참고 자료)
클래스에 값 타입(int)를 선언하면 클래스 인스턴스와 함께 heap에 저장된다. 동일하게 값타입인 구조체를 이에 대입해보면 당연하게 클래스 인스턴스와 함께 힙에 저장되어야 한다. 그렇기 때문에, 구조체(값타입)이라고 해서 무조건 스택에 저장되는 것이 아닌 '주로' 스택에 할당된다.
반대로 클래스가 구조체 안에 있을 경우를 생각해보자.
구조체는 값타입이기 때문에 스택에 할당된다. 이때 구조체 안에 참조타입이 있다면 해당 변수는 스택에는 주소를 저장하고 힙에 할당된다.
struct는 왜 상속이 불가능한가?
public interface ISimpleInterface{ }
public class SimpleClassA{ }
public class SimpleClassB : SimpleStructA { } //오류 발생
public class SimpleClassC : ISimpleInterface { }
public struct SimpleStructA { }
public struct SimpleStructB : SimpleStructA { } //오류 발생
public struct SimpleStructC : ISimpleInterface { }
struct와 class는 문법적으로는 유사하게 생겨도, 존재 이유가 조금 다르다. 클래스는 실세계의 객체를 추상화하려는데 그 존재의 이유가 있지만, 구조체는 데이터를 담기 위한 자료구조로 사용된다.
struct가 상속을 지원하지 않는 이유
1. 메모리 효율성 및 성능 최적화
값 타입은 독립적인 데이터 복사를 통해 성능을 최적화하도록 설계되어있다. 만약 상속이 가능해지면 부모와 자식 간의 메모리 구조가 복잡해져 메모리 효율성이 떨어지고, 성능에 부정적인 영향을 줄 수 있다. 이는 값 타입의 목적에 맞지 않는 방식이다.
2 .참조 타입과의 차별성
class는 객체 지향 프로그래밍에서 상속과 다향성을 통해 구조를 확장할 수 있도록 설계되었지만, struct는 이런 특성을 가지지 않도록 설계되었다. struct는 작고 독립적인 데이터 묶음으로서 간단한 역할을 수행하며, 값 타입의 특징을 갖도록 하기 위해 상속과 같은 복잡한 기능을 배제했다. struct가 상속을 지원하지 않음으로써 참조 타입과 값 타입 간의 명확한 역할 분담이 가능해진다.
요약하자면, C#에서 struct(값 타입)은 메모리 효율성, 독립적 복사, 단순성을 위해 상속을 지원하지 않으며, 필요시 인터페이스를 통해 다향성을 구현할 수 있다.
struct가 heap에 저장된다는 괴담(?)
ms에서 struct는 16바이트 미만을 적당한 크기라고 말한다. 그와 함께 16바이트가 넘어가면 heap에 저장된다는 얘기가 있다. 이는 성태님 글에서 해소할 수 있다. 그렇다면 왜 16바이트를 적당한 크기라고 말할까? 이 역시 성태님 글에서 힌트를 얻을 수 있었다. 결론적으로 얘기하자면, 16 바이트 크기에 대해서는 레지스터 하나로 처리할 수 있어 구조체의 권장 크기가 된 것입니다. 이러한 이유 뿐만 아니더라도, struct의 크기가 너무 크면 스택에 할당될때 부담될 수 있다. 따라서 16바이트 제한은 struct가 스택에 할당되었을 때 성능적인 측면에서 권장되는 기준이다.
- 참고 문서
- https://www.sysnet.pe.kr/2/0/12619
- https://www.sysnet.pe.kr/2/0/12620?pageno=0
- https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/value-types
- https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/builtin-types/struct
'STUDY > C#에 대한 다양한 공부' 카테고리의 다른 글
[C#] Array vs List vs ArrayList (0) | 2024.11.12 |
---|---|
interface는 인스턴스는 못 만들지만 참조는 만들 수 있다? (1) | 2024.10.03 |
[C#] Find() vs FirstOrDefault() (1) | 2023.09.05 |
.Any() (0) | 2023.09.05 |
[C#] List.Clear() vs List = null (0) | 2023.01.30 |