C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 예제소스
//struct (구조체) 생성
//가비지 컬렉팅의 대상이 아니고
//스택메모리에 할당되는 struct
struct MyStruct
{
//구조체에서는 미리 할당이 안됨. class에서는 됨.
//public int i = 10; //에러 - 구조체에는 인스턴스 필드 이니셜라이저를 사용할 수 없습니다.
public int i;
public int j;
//struct에서도 생성자를 몇가지 조건하에 만들 수있다.
//1. 매개변수가 무조건 있을 것
//2. 생성자 안에서 struct의 변수에 값을 모두 할당할 것
//매개변수가 없는 생성자는 불가
//public MyStruct()
//{
//}
public MyStruct(int num1, int num2) //인자 수가 꼭 변수 수에 맞추는 것은 아니다.
{
i = num1;
j = num2; //하나만 해도 안되고 변수 모두에 값을 할당해야 한다.
}
//함수는 그냥 만들 수 있다.
public void Show()
{
Console.WriteLine("i : {0}, j : {1}", i, j);
}
}
//class생성
class MyClass
{
public int i = 10;
public void Show()
{
Console.WriteLine("MyClass i : {0}", i);
}
public override string ToString()
{
//return base.ToString(); //base는 부모 타입. object
return base.ToString() +"는 i가 " + i + "입니다";
}
public override bool Equals(object obj)
{
//as로 캐스팅
MyClass other = obj as MyClass;
if(other != null)
{
if(other.i == this.i)
{
return true;
}
}
return false;
}
}
static void Func1(object o)
{
MyClass my = o as MyClass;
if(my != null)
{
my.Show();
}
{
Console.WriteLine("MyClass가 아니다." + o.ToString() + "입니다");
}
//메인 함수
static void Main(string[] args)
{
//MyStruct s1; //에러 - 할당 되지 않은 것은 사용 할 수 없다.
//s1.Show();
MyStruct s1 = new MyStruct(); //기본 생성자, 안만들어도 자동으로 있다.
s1.Show();
MyStruct s2; //생성 없이 사용 방법
s2.i = 5; //변수에 모두 값을 할당 한다.
s2.j = 6;
s2.Show(); //그러면 new없이 사용 가능 하다.
MyStruct s3 = new MyStruct(100, 200); //별도의 생성자로 할당
s3.Show();
MyStruct s4 = s2; //class같은 경우는 heap메모리에서
//같은 것을 참조하지만
s2.i++; //struct에서는 값 복사를 한다.(별개로 복사, 깊은 복사)
s2.Show();
s4.Show(); //결과가 다르다
//class 할당
MyClass c1 = new MyClass(); //class는 무조건 new로 heap에 할당
Console.WriteLine(c1.ToString()); //class 는 object 타입을 기본적으로 상속 받는다.
MyClass c2 = new MyClass();
c2.i = 10;
if(c1 == c2) //class는 ==로 비교하면 주소값을 비교 한다.
{
Console.WriteLine("c1과 c2는 같다.");
}
else
{
Console.WriteLine("c1과 c2는 다르다."); //주소값이 다르기 떄문에 false
}
//비교함수 재정의 하여 처리
if (Object.Equals(c1, c2)) //MyClass의 public override bool Equals(object obj) 를 탄다.
{
Console.WriteLine("c1과 c2는 같다."); //i값이 같아서 true
}
else
{
Console.WriteLine("c1과 c2는 다르다.");
}
//object;
//박싱언박싱(Boxing, Unboxing)
//class나 struct나 기본적으로 object class를 상속받고 있어
//object를 인자로 받는 함수에 인자로 들어 갈 수 있다.
Func1(c1); //class는 같은 heap 메모리에서 참조만 넘겨준다.
Func1(s1); //구조체를 object로 받으면 heap에 new 로 새로 생성된다.(본체는 stack에 남아있다.)
//메모리 낭비. 복사체는 가비지컬렉터 기다림.
Object obj = s1; //박싱이 일어남.(stack에 있는 struct가 object 클래스에 들어가야 하므로 Stack에서 Heap으로 모두 복사된다.)
MyStruct s5 = (MyStruct)obj; //언박싱(heap에 있는걸 Stack에 복사한다. 매우 리소스를 까먹으므로 안좋다.)
//int, float같은 기본 형은 다 struct이다.
string str1 = "abc";
string str2 = "abc";
if(str1 == str2)
{
//class 타입은 주소값을 비교한다. 하지만...
//string은 class 타입이지만
//너무 자주 사용되기에 이미 값비교로 override 되어있다.
Console.WriteLine("str1 == str2는 참이다."); //참으로 나온다.
}
else
{
Console.WriteLine("str1 == str2는 거짓이다.");
}
}
'공부 > C#' 카테고리의 다른 글
파일 저장 - FileStream, StreamWriter, WriteAllText, WriteAllLines (0) | 2016.05.12 |
---|---|
컬렉션(Collection), 제네릭 컬렉션(Generic Collection) - 예) ArrayList, List<T> (0) | 2016.05.11 |
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 개념 (0) | 2016.05.11 |
정렬 Array.Sort, Array.Reverse (0) | 2016.05.10 |
추상 클래스, 추상 함수(abstract), 인터페이스(interface) (0) | 2016.05.09 |