본문 바로가기

프로그래밍/C#

C++와 C#간의 차이점 정리에 덧붙여

2008/08/19 08:47

이번주는 틈틈이 검색 엔진과 메타 블로그 사이트를 시간순으로 훑으면서 국내 블로거들이 C#을 주제로 쓴 글을 하나씩 읽어 보려고 계획하고 있는 중이다. 그 중 C++와 C#간의 차이점 정리라는 재미있는 글을 발견했는데 내용 중에 약간 잘못된 부분이 있어 지적하려고 한다.

C++과 C#의 차이점 #1: 선행처리기를 쓰지 않습니다.

C#에서도 선행처리기를 쓴다. C++와의 차이점이라면 선행처리기가 컴파일러 안에 통합되어 있다는 것.

C++와 C#의 차이점 #3: Application을 의미하는 클래스가 꼭 있어야 합니다. 프로그램 진입점이 ApplicationClass.Main() 이네요. Java는 ApplicationClss.main() 인데… 마치 대학교때 친구 숙제 베껴서 낼 때 변수 이름만 바꾼 듯한 느낌이 드는 것은 저만의 느낌일까요 ?

C#의 Main()은 리턴 값을 가질 수도 있고 안 가질 수도 있고 파라미터를 가질 수도 있고 안 가질 수도 있고 private으로 선언해도 되고 public으로 선언해도 되는 등 자바의 main()에 비해 유연성이 높다. 단순히 변수 이름만 바꾼 것보다는 조금 더 다르다.

C++와 C#의 차이점 #7: 상속 계층의 꼭대기에 언어 수준의 object(Java 에서는 Object) 라는 class가 있습니다. 각종 언어 수준의 작업을 일관된 인터페이스로 해주는 녀석이겠죠. 이것도 type system에 구멍이 생길 수 있어서 논란의 여지가 있습니다.

엄밀히 구분하면 object는 C#의 키워드고 실제 클래스명은 자바와 같이 Object다(전체 명칭은 System.Object). 오남용하면 타입 시스템에 구멍이 생길 수 있는 건 맞지만 C# 2.0부터는 지네릭을 지원하기 때문에 논란의 여지가 될 수 있었던 것은 먼 과거의 일.

C++와 C#의 차이점 #8: 문자열 리터럴이 char * 가 아니라 언어 수준의 utf-16(Java 에서 String 은 utf-8 이던가요 ?) 유니코드 문자열 클래스인 string의 인스턴스이다.

자바도 C#과 마찬가지로 String 타입이 UTF-16이다.

C++와 C#의 차이점 #9: Java처럼 pointer 가 없다. 큰 장점이자 단점이 될 수 있겠지. 그런데 이제 단점으로 작용하는 영역이 별로 클 것 같진 않다. OS나 Device Driver 에서나 쓰기 어렵지 다른 곳에서 웬만하면 쓰일 수 있을테니까.

C#에도 포인터가 있다. C#으로 만든 OS도 있다.

C++와 C#의 차이점 #14: 가상 함수와 순수 가상 함수를 나타내는 키워드를 분리했습니다. 가상 함수는 virtual, 순수 가상 함수는 abstract! subtype 이 override 할 때는 override 라는 키워드를 써야 합니다. 순수 가상 함수는 interface 와 기능이 겹칠 것 같은데… 왜 class 에서도 중복해서 지원할까? 단일 상속 제약때문에 그럴까요 ?

C++도 가상 함수와 순수 가상 함수를 명시적으로 구분하지만 단지 괴악한 "= 0" 문법을 사용한다는 점이 C#과 다르다. 인터페이스가 있는데도 굳이 순수 가상 함수를 둔 이유는 일부 함수는 상위 클래스에서 미리 구현하고 일부 함수는 하위 클래스에 구현을 맡기는 형태의 디자인이 가능하기 때문. 반대로 정말 순수하게 순수 가상 함수로만 이루어진 클래스를 만든다면 인터페이스를 쓰는 쪽이 훨씬 깔끔하다.

C++와 C#의 차이점 #15: 형식 매개 변수라는 걸 통해 template과 같은 기능을 제공합니다. C++처럼 강력한 generic programming 이 가능한지는 모르겠지만.

형식 매개 변수가 아니고 지네릭을 통해 C++ 템플릿과 비슷한 기능을 제공한다(형식 매개 변수는 지네릭의 일부임). 지네릭을 제공하므로 당연히 지네릭 프로그래밍이 가능하고, 내 생각에는 C++보다 더 쓰기 쉽고 강력하다(C#이니까 다소간의 성능 저하는 이해와 사랑이 필요...^^).

C++와 C#의 차이점 #19: scope operator 가 '::' 이 아니라 '.' 입니다. 전 이게 더 좋은 것 같아요. 어떤 경우는 :: 을 쓰고 어떤 경우는 . 을 쓰고 그랬는데,

(이건 잘못된 내용은 아니지만 부연 설명 차원에서) C#에도 :: 연산자가 있다. 예를 들어 C++에서는 전역 네임스페이스를 나타낼 때 ::std처럼 쓸 수 있지만 C#에선 global::System이라고 쓴다. 주의: 모양은 비슷하지만 용법에 차이가 있다.