티스토리 뷰

반응형

객체지향 프로그래밍을 하게되면 반드시 "클래스"라는 용어는 접하게 되어있다.

클래스라고 하는것은 변수나 메소드등의 기능을 담는 틀 정도로 보면 되는데

비슷한 개념으로 구조체라는 녀석이 있다.

아마 C, C++을 선행학습하지 않고 C# 또는 java를 배운사람들은 구조체라는 게 낯설지도 모르겠다.

구조체라는 이름도 어색하고 언뜻 보면 구조체와 클래스는 선언방식, 모양, 기능이 비슷하기 때문이다.

이 둘의 차이가 뭔지도 좀 명확히 할 필요가 있을거 같아서 이번 기회에 한번 정리해 보고자 한다.

먼저

구조체(struct)

구조체의 기본적인 형식은 다음과 같다.

struct tempStruct // 구조체 이름
    {
        // 변수 타입 변수명;
        int age;
        string mName;
    }

구조체가 하는일은 변수들의 집합을 메모리에 올리거나 초기화 하는 일이다.

구조체를 왜 사용하냐 하면

위 코드처럼 변수가 두개밖에 없는 작은 프로젝트(두개밖에 없는 프로젝트는 없겠지만...)의 경우는 괜찮을지 모르겠지만

프로젝트가 대형화되면 될수록 사용하는 변수를 통제하고 관리하는 것이 갈수록 어려워지게 되는데

(수백개 또는 수천개의 변수명을 겹치지 않게 계속 만들어야 하니까...)

이런 어려움을 해결하기 위해 변수를 구조체에 담아 사용하는 방법을 고안했다고 알고있다.


구조체를 사용하기 위해서는 다음과 같이 구조체를 선언하는 작업을 해야 하는데

몇 가지 방법이 존재한다.

class Program
    {
        static void Main(string[] args)
        {
            tempStruct tmp;
            tempStruct tmp2 = new tempStruct();
        }
    }

위 코드를 보면

main 메소드 안에 tempStruct 구조체를 메모리에 올리기위해 두 가지 방법으로 선언하도록 했다.

그런데 사실은

tempStruct tmp; 처럼 new 키워드를 사용하지 않더라도

암시적으로 new 키워드를 사용하도록 내부에서는 동작하게 되어있기 때문에

어떤 방법을 사용하더라도 결과적으로는 같다고 보면 된다.

위 코드처럼 main 메소드에서 구조체를 선언했다면 구조체 변수를 통해 구조체 안의 멤버변수의 값을 입력하는 등의

핸들링이 가능한데 여기서 주의할 점이 있다.

비쥬얼 스튜디오를 사용한다면 tmp라는 구조체 변수 뒤에 점을 찍으면 인텔리전스 시스템에 의해 사용할 수 있는 변수명 또는 함수의

리스트가 나오게 되는데 위 코드를 그대로 사용하면 구조체 안의 age, mName 변수는 보이지 않는다는 것이다.

이것은 접근제한자라는 키워드와 관계된 것으로 변수를 선언할때 어디까지의 접근을 가능하게 하는지 정의할 수 있게 하는 것이다.

간단히 정리하자면

public : 어디서나 접근 가능

protected : 상속관계에서 접근 가능

private : 동일 클래스 내에서만 접근 가능

의 키워드를 변수 앞에 붙여주는 것으로 접근을 제한하며

위 코드에서는 구조체 안에 선언된 변수의 접근제한자가 public으로 되어 있지 않아 해당 변수에 접근할 수가 없게 된다.

따라서 접근이 불가능한 변수를 사용하게 되면 오류가 발생하게 되며

비쥬얼 스튜디오의 인텔리전스 시스템에서는 해당 변수명이 보이지 않게 되는 것이다.

접근제한자를 public으로 한 것과 하지 않은것을 비교해 보면 다음과 같은 결과가 된다.

(참고로 구조체는 암시적으로 접근제한자가 public으로 되어있다.)

위 화면과 같이 구조체에서 선언한 변수 중 public으로 선언한 age는 main메소드에서 접근이 가능하지만

mName같은 경우는 public이 아니기 때문에 main메소드에서 접근이 불가능하게 되는것이며

비쥬얼 스튜디오에서는 개발의 편의성을 위해 인텔리전스 시스템이 그래픽으로 확인할 수 있게 가이드를 해주게 되어있다.


위와 같이 접근제한자를 public으로 해서 구조체의 변수의 값을 메모리에 저장할 수 있으며

다른 방법으로는 생성자 호출을 이용해서 구조체 변수의 값을 메모리에 올리는 것도 가능하다.

다음 코드를 보기로 하자.

 struct tempStruct
    {
        // 변수 타입 변수명;
        public int age;
        string mName;

        public tempStruct(int age, string mName)
        {
            this.age = age;
            this.mName = mName;

            Console.WriteLine("struct 생성자에서 할당된 나이는 " + age + "살이고 이름은 " + mName + "입니다.");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            tempStruct tmp;
            tmp.age = 25;
            Console.WriteLine("main메소드에서 할당된 나이는 " + tmp.age + "살입니다.");

            tempStruct tmp2 = new tempStruct(30, "길동이");
        }
    }

main메소드에서 구조체 선언을 tmp로 한번, new키워드를 사용한 tmp2로 한번 했으며 다음과 같은 동작이 일어난다.

1. 구조체 변수명 tmp이 호출될 때

위에서 잠깐 얘기했듯이 

tempStruct tmp;와

tmpStruct tmp = new tempStruct(); 는 동일한 동작을 하도록 되어있다.

따라서 구조체의 디폴트 생성자도 호출을 하겠지만 구조체의 디폴트 생성자를 구현하지 않았기 때문에

디폴트 생성자는 호출되겠지만 개발자의 입장에서는 아무런 동작이 일어나지 않는 것처럼 보인다.

2. 구조체 변수명 tmp2가 호출될 때

대신 매개변수를 받도록 오버로딩된 생성자가 호출되어 this 키워드로 연결된 구조체 변수의 메모리에 값을 할당하게 된다.

따라서 생성자가 호출될 때 입력된 매개변수가 구조체 생성자를 호출할때 값이 넘어가서 구조체에서 변수값이 입력된다.

위 코드를 실행한 결과는 다음과 같다.

main 메소드에서 구조체의 변수값을 할당한 것과

구조체의 생성자를 호출해서 변수값을 할당한 것을 알 수 있다.

참고로

구조체에서 선언된 변수의 값을 구조체에서 초기화하면 에러가 발생하게 된다.

하지만 특수한 경우 구조체에서도 변수값을 줄 수 있는데

변수를 선언할때 "const" 또는 "static"으로 선언해서 상수로 사용하는 경우에는 가능하다.



여기까지 구조체에 대해 (구조체가 뭔지, 구조체를 왜 사용하는지, 구조체를 어떻게 사용하는지)

간단히 알아봤는데....

.....

.................

역시나 분량조절에 실패해서

클래스에 대한 애기는 하나도 못하고 이야기가 길어지고 말았다....

나도 시간이 무한정 있는게 아니라서...

클래스에 대한 얘기는 다음번에 다시 정리하기로 하고 이번편은 여기서 마치는걸로....

끝~!


반응형
댓글
반응형
05-19 10:21
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함