작성
·
145
답변 1
2
안녕하세요.
저도 이문제로 고민을 많이 했는데요. 말씀하신 동작은 클래스의 동작입니다. 예를 들어서 구조체의 다음코드가 있으면 이 문장을 실행해보면 오류로 초기화가 실행되지 않았다고 나옵니다.
메모리가 없다는 내용이 아니고요.
// 1
StructPos pos;
print(pos);
이 상황에서 다음과 같이 해주면 정상 동작합니다.
// 2
StructPos pos;
pos.x = 1; pos.y = 2; pos.z = 3;
print(pos);
그리고 다음과 같이 해도 잘 실행됩니다. 구조체가 new 를 통해서 메모리가 생성된다고 생각하면 위에 있는 두번째 코드는 실행이 되면 안됩니다.
// 3
StructPos pos = new StructPos();
print(pos);
반면에 클래스의 경우는 다음과 같이 문장이 실행되면 인스턴스가 없다는 오류가 생깁니다.
//4
ClassPos cPos;
print(cPos);
아래의 문장도 마찬가지이고요.
// 5
ClassPos cPos;
cPos.x = 1; cPos.y = 2; cPos.z = 3;
print(cPos);
클래스 같은 경우는 꼭 다음과 같이 new 를 붙여서 인스턴스를 만들지 않으면 실행이 안됩니다.
// 6
ClassPos cPos = new ClassPos();
cPos.x = 1; cPos.y = 2; cPos.z = 3;
print(cPos);
그래서 저도 고민을 많이 했는데 내린 결론은요.
구조체에서의 new StructPos(); 은 그냥 생성자의 호출입니다.
구조체의 경우는 값타입이라 그자리에 가보면 데이터가 있습니다. 즉 메모리생성이 이미 끝난 상태이고 초기화만 진행되면 되지만 이것을 new 로 해도 되는 이유는 클래스의 문법과 형식을 동일하게 만들기 위함이라고 생각합니다. (2번 코드에서 초기화를 진행하지 않으면 코드가 실행되지 않는다는 이야기는 초기화가 필요하지 메모리할당이 필요한 것이 아니라고 예상할수 있습니다)
클래스에서의 new ClassPos(); 은 생성자의 호출과 더불어 인스턴스의 메모리 생성입니다.
클래스의 경우 레퍼런스의 타입이라 말씀하신 대로의 내용대로 동작합니다. 클래스는 new로 만들지 않으면 실행이 되지 않습니다. 스택에 변수의 참조가 있고 이 참조가 힙에 있는 실제 데이터를 가르키고 있습니다.
C# 언어 설계자들이 초보자들이 많이 접근하기를 원해서 같은 문법으로 다른 기능을 만들었다고 생각하고 있습니다. 초보자들의 입장에서 보기에는 혼돈스러울 경우 무조건 둘다 new 를 실행하면 되기 때문입니다. 구조체가 new로 실행되어도 메모리는 이미 초기화 되어 있는 상태이고 문법의 통일성을 위해서 new도 가능하다라는 것입니다. (4번코드나 5번코드가 실행이 안된다는 것을 보시고 오류 메시지를 보시면 이해가 될 것입니다.)
사실 언어도 프로그래밍의 산물입니다. C# 에서 선언한 스펙을 따라서 C# 언어가 만들어집니다. 닷넷버전에 따라서 구현의 상세 내용이 달라지기 때문에 실제의 구현된 메모리 구조는 저도 알지 못합니다. (제가 설명하는 메모리는 언어스펙에 따른 간략화딘 메모리구조입니다) 나중에 C# 어셈블리를 조금 공부해서 피씨용에서라도 메모리를 따라가 보고 이 내용을 다시 설명드리겠습니다만 우선 제가 알고 있는 내용은 이렇습니다.
구조체는 어떻게 선언하든 메모리에 생겨납니다. 그저 초기화가 되었는지(new로 선언하여 생성자를 호출) 초기화가 되지 않았는지(그냥 변수로 선언) 의 차이가 있습니다.
클래스는 꼭 new로 선언해야 합니다. 메모리 할당이 이루어져야 하기 때문에 new 를 하지 않으면 실행이 되지 않습니다. 문법이 똑같은 이유는 초보자가 사용하기에 미심적으면 무조건 new 를 하면 되므로 이렇게 선언합니다.
예를 들어 StructPos pos = StructPos(); 이 것이 없는 이유는 통일성이 없기 때문이라고 생각합니다.
공부해본 바로는 C#의 언어 설계의 철학이 내부로 들어가는 것은 어려워도 외부로 나오는 것들은 통일성 있게 보여주고자 하는 것이라고 판단하고 있습니다.
C# 첫 질문이시네요. 정말 감사합니다. 좋은 하루 되십시오. ^^