상세 컨텐츠

본문 제목

[C#] struct 구조체 관련

본문

반응형

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

출처: http://clairehjl.blogspot.com/2013/05/struct-class-in-c.html

struct 와 class In C#

 

C++의 경우 struct와 class의 차이는 선언된 변수나 함수가 기본적으로 public 이나 private이냐의 차이이다. class의 경우 private이 기본으로 선언된다. 이는 C++ 언어의 encapsulation 의 메카니즘에 의한 차이로 보인다.

그럼 C#에서 struct와 class 의 차이는 뭘까..

C++에서와 달리 두가지 모두다 private 으로 기본 선언된다.
또한 Structs는 파라미터가 없는 Constructor를 가질 수 없다.

// 구글을 검색하면 아래와 같은 글이 많이 보인다.. 하지만 몇가지 아티클과 책을 읽은 후 이부분에 의심이 생기기 시작함... 흠..

  • struct의 경우 stack 에 저장되고 class의 경우 heap에 저장된다.



저 말은 struct가 value type이기 때문에 stack 에 저장된다고 하는거 같지만.
아래 글을 보면 의심이 들기도 한다. 단지 value type이라고 해서 stack에 저장되지 않는다는 말이다. 메모리의 어떤위치에 저장 될 것인가는. 변수의 life time에 따라 컴파일에서 정해진다고 한다. 그래서 일반적으로 (MS VS의 경우) 임시변수나 로컬변수가 stack 에 저장된다는 것이다.
http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

struct로 생성 할 경우 memory fragmentation 의 경우도 발생되지 않을 것 같고.. Garbage Collection의 호출도 줄 일 수 있을거 같다...고 생각했지만 지금은 이부분도 좀더 생각해봐야겠다..;;

여기서 분명히 다른 점은 struct의 경우 함수 parameter로 넘길때 pass by value로 인식하기 때문에 reference 로 값을 넘겨야한다. 반대로 class의 경우 pass by reference 로 넘어간다.

아래 struct가 pass by value로 처리되는 예제이다.



public struct TestStruct
{
    public int value;
}

public class TestClass
{
    void function(TestStruct ts)
    {
        ts.value = 5;
    }

    void main()
    {
        TestStruct ts = new TestStruct();
        ts.value = 10;

        function(ts);

        Console.WriteLine("{0}", ts.value);
    }
}


Output: 10

이로인해 생기는 문제가 있는데..


public struct TestStruct
{
    public int value;
}

public class TestClass
{
    void function(TestStruct ts)
    {
        ts.value = 5;
    }

    void main()
    {
        TestStruct ts = new TestStruct();
        ts.val = 10;

        List<TestStruct> list = new List<TestStruct>();
        list.Add(ts);

list[0].val  = 5;

        Console.WriteLine("{0}", list[0].val);
    }
}

위에서 처럼 List에 Add했을 경우 임시변수에 값을 할당하게 되어 에러가 발생한다.

간단히 해결하는 방법은



void main()
{
    TestStruct ts = new TestStruct();
    ts.val = 10;

    List<TestStruct> list = new List<TestStruct>();
    list.Add(ts);     

TestStruct temp = new TestStruct();
temp.val = 6;
list[0]  = temp;

    print(list[0].val);
}

메모리를 새로 할당해서 값을 셋팅한후 넘겨주거나
Custom Container를 만들어서 operator = 오버라이딩을 할까 했으나...-_-

msdn에 문서에서 = 은 오버라이딩을 할 수가 없다...oTL

http://msdn.microsoft.com/ko-kr/library/8edha89s(v=vs.71).aspx

뭐 그래서 위에처럼 처리하면 될 것 같다...털썩..

아 그리고 오버라이딩이 안된다면 Deep Copy를 이용해 하는 방법도 있을듯... 이건 직접 해보지 않아 아직 확실하진 않다..-_-ㅋ


어제 저걸 고민하다가 Unity3D에서는 struct를 어떻게 사용했나 궁금해서 봤더니..
Vector가 struct로 구현되어 있었다.. 반면 GameObject의 겨우 extern 의 외부 객체들을 들고 있어 class로 구현되어 있는 것을 볼 수 있었다..

 

 

 

 

반응형

 

728x90

 

 

 

=================================

=================================

=================================

 

 

출처: https://076923.github.io/posts/C-17/

 

구조체 (Struct)


구조체 (Struct)는 클래스 (Class)와 비슷한 부분이 많습니다. 클래스와 동일한 구조로 사용할 수 있습니다. 하지만 구조체는 클래스와 다른점이 있는데, 크기가 작으며 간단합니다. 또한 상속이 필요가 없는 경우에 사용합니다.

 

특징클래스구조체

선언 class struct
형식 참조 형식 값 형식
복사 얕은 복사 깊은 복사
인스턴스 생성 new연산자, 생성자 필요 매개 변수가 없는 생성자 선언 불가

 

참조 형식, 값 형식이란? : 9강 바로가기

 

복사 (Copy)


프로그래밍을 진행하다보면 같은 양식을 복사해서 사용해야할 경우가 종종 있습니다. 복사에는 2 종류가 있으며 각각 큰 차이를 보입니다.

  • 얕은 복사 (Shallow Copy) : 얕은 복사란 복사본의 값을 바꾸엇을 때 원본의 값도 바뀌는 형태입니다. 클래스에서 얕은 복사가 사용됩니다. 쉽게 설명하자면 word 파일을 작성하였을 때, 바로가기 아이콘과 동일합니다.

 

 

class test_class
{
    public int first;
    public int second;
}

private void Form1_Load(object sender, EventArgs e)
{
    test_class original = new test_class();

    original.first = 10;
    original.second = 20;

    test_class copy = original;
    copy.first = 30;

    Console.WriteLine("{0}, {1}, {2}, {3}", original.first, original.second, copy.first, copy.second);
}

실제 출력 값 : 30, 20, 30, 20

 

  • 깊은 복사 (Deep Copy) : 깊은 복사란 복사본의 값을 바꾸어도 원본의 값은 바뀌지 않는 형태입니다. 구조체에서 깊은 복사가 사용됩니다. 쉽게 설명하자면 word 파일을 작성하였을 때, 복사ㆍ붙여넣기와 동일합니다.

struct test_struct
{
    public int first;
    public int second;
}

private void Form1_Load(object sender, EventArgs e)
{
    test_struct original;

    original.first = 10;
    original.second = 20;

    test_struct copy = original;
    copy.first = 30;

    Console.WriteLine("{0}, {1}, {2}, {3}", original.first, original.second, copy.first, copy.second);
}

 

 

실제 출력 값 : 10, 20, 30, 20

 

 

=================================

=================================

=================================

 

 

반응형


관련글 더보기

댓글 영역