반응형

클래스가 뭘까? 그냥 하나의 사용자 정의 자료형이라고 생각하면 맘편할꺼다.. 캡슐화니 뭐 그런 어려운거 차차 나오면 그런게 있나보다 하고 지나가라.. 사소한거에 목숨걸지 말란 말이다..

클래스가 자료형이라고? 자 보자..
우리가 제일 많이 쓰는

int a;

이거 integer형 변수 a 선언한거 맞지?

struct struct_a
{
   ....
};

struct_a sa;

이거 struct_a형 변수 sa선언한거 맞지?

class class_a
{
....
};

class_a ca = new class_a();

약간은 달라보이지만 class_a형 변수 ca 선언한거 맞다. 왜 new 요따구께 들어갔냐고..? 앞에꺼 잘봐라.. 이놈은 참조형이라서 그냥 냅다 이름만 불러놓구 뭐 할려고 하면 친절하게 "뭥미?" 날려주신다.

다른 사소한 것들은 사포시 무시하고 넘어간다.. 궁금하면 책 찾아봐라.. 누누히 이야기 하지만, 사소한거에 목숨걸면 chapter 1만 까맣게 변해서 한쪽 구석탱이에 쳐 박혀 있는 책 많이 보게 될꺼다..

뭐 구현하는 방법상으로 보면 struct나 class나 큰 차이는 없어보이나, C++에서는 기본 속성이 public이냐 private냐인 것과 reference냐 value냐 이정도 차이 이외엔 차이점을 찾기가 힘들었다.. C#에서도 마찬가지 일거라 생각되지만, C#에서는 간단한 자료형에는 struct를 사용하고 좀 복잡해지면, class를 사용하길 권하고 있다..

뭔소리냐면, 내가 무슨 작업을 하는데, int, char, double 이 세가지 자료가 다른 건 필요없고 함께 움직이기만 하면 돼.. 그럼 이걸 각각 정의해서 델꾸 댕기는것 보단 하나로 묶어서 델꾸 댕기는게 훨씬 편하잖아..
그럴때 struct를 사용하란 이야기야..
struct struct_a
{
   int a;
   char b;
   double c;
};

뭐 이런식으로..

그런데 이녀석이 함께 움직이면서 좀 복잡한 일을 해야돼.. 어떨땐 a^2을, 어떨땐, b를 두번찍은 문자열을 뭐 그런작업을 해야해.. 그럼 class를 쓰란 소리야..

class class_a
{
   int a;
   char b;
   double c;

   int sqareA() { return a^2; };
   void doublePrintB() { Console.WriteLine( b + b); };
};

뭐 요따구로 말이지... (이거 C++이랑 헤깔려서 제대로 하는지 모르겠다..)

뭐 권장사항 따라해서 나쁠건 없으니 앞으론 권장사항대로 하자..

그런데 struct에도 있지만, class란 녀석은 접근 지정자라고 불리우는 녀석이 있어.. 그게 뭐냐고? 말 그대로 접근할 수 있는 방법을 지정해 주는거야.. 어렵다고? 자 그럼 한번 보자고..

우선은 C++ 과 C# 둘의 접근 지정자..(Accessibility Levels)를 한번 보자..

C++에서는 private, protected, public 이 세가지만 존재했는데, C#에선 protected internal, internal이 더 생겼다.

그럼 우선 private을 보자
C++ 에서는 Class members declared as private can be used only by member functions and friends (classes or functions) of the class. 라고 했고, C#에서는 Access is limited to the containing type.이라고 했다.
둘이 비슷해 보이지만, 한가지 차이점이 있다.. 바로 friend다.. 즉, C++에서는 private로 선언된 클래스 멤버는 오로지 맴버함수와 클래스의 friend(클래스 또는 함수)에 의해 사용되어 질 수 있다라고 했고, C#에서는 달랑 접근이 포함되는 타입에 한정된다(해석이 맞나 모르겠다..나도 영어 못한다..)라고 되어 있다. 즉, C#에서 private로 선언된 넘은 멤버 이외엔 아무도 못 건들인다는 소리가 된다. 그리고 C#에선 friend란 키워드가 없다..

다음으로 protected..
C++에서는 Class members declared as protected can be used by member functions and friends (classes or functions) of the class. Additionally, they can be used by classes derived from the class.라고 했고, C#에서는 Access is limited to the containing class or types derived from the containing class.이라고 했다. 이것도 friend란 녀석이 차이를 보이고, private과 다른점은 바로 derived class에서도 사용가능하다는 것이다.

그 다음 public..
아마도 제일 많이 보는 녀석이 아닐까 싶다.. C++에서는 Class members declared as public can be used by any function. 라고 했고, C#에서는 Access is not restricted.이라고 했다. 즉, 개나 소나 아무나 찝적거려도 된다는 이야기다.

여기까지는 C++과 C#에 공통적으로 있던 접근 지정자였고, C#에서 나타난 녀석들을 보자.
internal - Access is limited to the current assembly. 이라고 되어 있다. 현재 어셈블리로 접근이 제한된다.. 
protected internal -  Access is limited to the current assembly or types derived from the containing class. 이건 internal + protected로 보면 속 편할 것 같다. 
자 그럼 위 두녀석이 뭘 의미하는지 보자.
 current assembly 이게 중요하다.. assembly 하니까 mov, jp, eax 이런거 막 떠오르는 당신.. 당신은 고수다.. 나좀 갈켜주라.. 여기서 어셈블리는 우리가 알았던 어셈블리 랭귀지의 어셈블리와는 좀 다른 CLR에 의해 생성된 중간 언어(MSIL 혹은 IL)으로 불리우는 녀석이다. 외형상으로 보면 exe, dll을 확장자를 가지고 있지만, JIT없이는 실행되지 않는 그런 녀석이다. 왜 이이야기를 하냐고? 지금까지 나왔던 예제..(Hello, World!밖에 없다..)같이 짧막한 녀석이야 파일 하나에 딱 때려넣고 컴파일 해서 돌리면 되지만, 어느정도 규모가 커지면 이리 저리 분리하기 시작한다. C++의 경우엔 파일이 분리되어 있더라도 header파일 include를 통해 이리저리 뛰어 댕기며 잘 만들어 주게 되지만, C#은 include란게 안보인다.. 눈 씻고 찾아봐도 안보인다.. 그자리에 using 어쩌고만 보일 뿐이다.. 이소리는 뭔소리냐? 이녀석이 한번은 컴파일 되어 어셈블리가 되어야만 다른 파일에 있는 녀석을 사용할 수 있게 된다는 소리다. 어셈블리가 뭔지 나왔지? 머리가 나빠서 이렇게 밖엔 설명 못하겠다. 아무튼, internal이란 녀석이 붙어면, 같은 파일 내에서만 접근이 가능하다는 정도로만 이해하면 쉬울꺼다..

그럼 protected internal은? 이건 internal + protected다.. or결합이다.

자 예를 들어보자..

/// test1.cs
using System;

class OutClass
{
    internal static void a()
    {
         Console.WriteLine("삼가 고인의 명복을 빕니다.");
    }
}

class test
{
    public static void Main()
    {
         OutClass.a();
     }
}

/// end

우선.. 이거 작성하던 이 순간에 학교때 친구녀석한테 전화가 왔다.. 아버님께서 돌아가셨다고..
혹여라도 이거 읽는 사람 있다면 좋은곳으로 가시라고 잠시 묵념이라도 해주기 바란다.

그럼 이제 다시 본론으로 돌아가서..
위와 같은 경우 잘 돌아간다.. internal 보이지? 같은 파일 안에 있기때문에 아무 문제없이 잘 돌아간다..

그럼 나눠보자.
/// test 1-a.cs
using System;

class OutClass
{
    internal static void a()
    {
         Console.WriteLine("삼가 고인의 명복을 빕니다");
    }
}
/// end
이녀석은 dll로 만들고...
C:\> csc /t:library test1-a.cs

/// test 1-b.cs
using System;

class test
{
   public static void Main()
   {
         OutClass.a();
    }
}
/// end
컴파일 해주면
C:\> csc /t:exe /t:test1-a.dll test.cs
그럼 에러가 발생하는게 보일꺼다.. (여기 모든 예제는 테스트 안해봤다..누가 좀 해보고 결과 알려주면 고맙겠다..)

아무튼 이 에러가 internal 속성때문에 발생하는 거다..

그러면 다음 protected internal
위 1-a 예제를 살포시 바꿔보자..
/// test 1-c.cs
using System;

class OutClass
{
    protected internal static void a()
    {
         Console.WriteLine("삼가 고인의 명복을 빕니다");
    }
}
/// end
이리 바꿔놓고 컴파일해보면 결과가 나온다...

그리고 마지막으로 자료형 별 사용가능한 접근 권한을 정리해 보면,

Members of

Default member accessibility

Allowed declared accessibility of the member

enum

public

None

class

private

public

protected

internal

private

protected internal

interface

public

None

struct

private

public

internal

private

이라고 MSDN에 친절하게 나와있다..

이외의 내용은 나중에 언급할 일이 생기면 언급하도록 하겠다..

반응형

+ Recent posts