C++ vs JAVA; only a skin-deep comparisons

Tags:

Motivated by 아커티렐.

Strongly Typed Language(강하게 형 지워진 언어 혹은 강한 형의 언어라고 번역)의 정의는 두가지입니다.

1. 컴파일 타임에 변수의 타입이 결정지워진다; 이 정의의 문제점은, 변수의 타입은 컴파일 시간에 정의되지만 실행시에는 변수의 저장소에 다른 타입이 저장될 수 있다는 것이죠. 그래서 또다른 정의가 2번인데,

2. 언제나 타입 에러를 찾을 수 있는 언어; 이 정의가 실제로 통용될 수 있는 정의고요. 보다시피 컴파일 타임이란 말이 쏙 빠져나갔습니다.

바인딩이란 말이, 변수의 선언과 그 변수가 저장되는 저장소간의 결합을 지칭하기 때문에.. 런타임 바인딩이라는 것은 실행시간에 저장소가 결정지워진다는 것이고, 타입 에러는 실행시간에 판단한다는 것이죠..

폴리모피즘(다형성)의 경우에는 상속 계층이 있을때 메소드가 virtual로 선언되면 (알고 있겠지만) 가상 테이블을 사용해서 실행시에 어떤 메소드를 실행할지를 결정합니다..

확실히 C++의 경우가 자바보다 훨씬 강력한 것이,

(1) 캐스팅을 함에 있어서 어떤 종류의 캐스팅 방식(static/dynamic)을 택할 것인지를 컴파일 타임에 결정지워줄 수 있고 (static_cast/ dynamic_cast/ reinterpret_cast),

(2) subtyping(=inheritance with interface. public 으로 상속 받는 경우), subclassing(inheritance with implementation. private 으로 상속 받는 경우)을 구별 할 수가 있죠. 반면 자바는 extends로 subclassing, implements로 subtyping을 지칭할 수는 있으나 extends 하면서 subtyping을 할 수도 있으므로 애매모호함..

(3) C++에서는 모든 메소드가 virtual이지 않으며, 필요에 의해 virtual로 선언하는 반면 자바는 모든 메소드가 virtual이어서 실행시 C++이 더 빠르게 다형성을 구현하며, 뿐만아니라 C++의 경우 매우 효율적인 구현으로 인해 virtual 메소드 호출시 5회의 추가적인 메모리 접근만 필요하여(C++의 창시자인 Bjarne Stroustroup 이 그렇다고 말했음), 스몰토크같은 언어보다 매우 우수한 성능을 보임.

(4) C++에서는 parametrized polymorphism(한마디로 template)이 가능하지만 자바는 그렇지 않죠. 하지만 JDK 1.5부터는 generic programming이 가능해졌으나, C++과 같은 meta programming은 불가능하죠. meta programming에 대한 참고 문서는 http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html에 있음.

(5) C++은 다이아몬드 형태로 상속이 가능하나 자바는 그렇지 않음. 물론 이것을 자바에서 복잡성을 제거했다고 말하지만, 실제로 두개의 인터페이스를 구현하는 클래스를 만들때 다음과 같은 구현을 하게 되죠…


public class Test extends Parent1 implements Parent2Interface {

    public Test(Parent2Interface p2) {
        this.p2 = p2;
    }

    public ... p2_method_1() {
        this.p2.p2_method_1();
    }

    public ... p2_method_2() {
        this.p2.p2_method_2();
    }
}

이런 식으로 부모중 하나의 모든 메소드를 일일히 구현하면서 이를 생성자에서 넘겨받은 p2에 모두 위임한다는게 일반적인 2개의 인터페이스를 구현하는 방법이지만, 실제로 이렇게 코딩하려면 열라 귀찮죠… 뭐 일장일단인 셈..

(6) C++의 경우는 friend 등의 다양한, 그리고 복잡한 접근이 가능하다.

(7) C++의 경우에는 연산자 오버로딩이 가능하죠. 심지어 자바는 문자열에 대해서도 = 연산자가 오버로딩되어있지 않아서 문자열을 비교할때는 stringVar1.equals(stringVar2) 와 같이 비교해야하는데, 이와같은 문자열 비교방식은 깜빡하고 ‘=’ 연산자로 비교해 버릴 경우 에러가 나기 쉽다는 문제가 있죠. 반면 C#은 연산자 오버로딩도 제공하죠. 물론 연산자 오버로딩의 단점은 많죠. 가장 큰 단점은 연산자가 어떻게 동작할 것인가를 사람들이 모두 다르게 생각할 수 있다는 점이며, 연산자를 오버로딩 했는지 안했는지 항상 점검하기 어렵다는 것이죠. 하지만, 연산자 오버로딩이 가능할 경우 기존의 코드를 매우 간단하게 고칠 수 있단 장점도 있죠. 예를들자면 메모리상에서 접근하는 프로그램을 디스크상에서 접근하도록 고칠 경우, = 연산자등을 파일 입출력으로 전환해버리면 되니까요. 하지만 자바에서 이런 작업을 한다면, 원 프로그램이 매우 잘 객체지향적으로 설계가 되어있지 않은한 완전 삽질이 되야함.

그러나 언어가 할 수 있는게 많다고 좋은 것만은 아닌것이… 너무 복잡하다는 거죠. 저만해도 C++로 짜라고하면 베이스 클래스 하나 만들고 베이스 클래스에 대한 복사 생성자 만들고, = 연산자 오버로딩하고 메모리 에러 안나는지 점검하고 나면 힘이 다 빠져서 다른 코딩을 못하겠단 생각이 들어버리는고로…

언어가 복잡함에 따라서 발생하는 문제는 (1) 사용자가 언어의 모든 기능을 익혀야 한다고 생각하여 큰 스트레스를 받음, (2) 사용자마다 복잡한 언어의 일부 기능만 사용하며 따라서 다른 사용자가 작성한 프로그램을 이해하기가 힘들어짐, (3) 읽거나 쓰기 힘들어짐.

그리하여 모 자바 서적에서는 ‘너희는 C++로 짜라. 우린 너희가 C++ 코딩을 끝내고 유지보수와 디버깅에 한참일 때 하와이에서 휴가를 즐기고 있을테니까.’ 하는 비아냥거리는 대사도 있더군요…

Software crisis 라는 개념이 나온뒤로 언어의 발전방향은 아무래도 생산성과 유지보수 편의성인거 같습니다.. 하지만 강력한 개념들이나, 보다 기계적인 수준에서의 접근이 가능하다는 장점은 미래에도 계속 중요한 것이다보니 (오죽하면 임베디드 하는 사람들은 C++도 안하고 C만 하잖아요)…

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *