티스토리 툴바


'Programming/C/C++'에 해당되는 글 5건

  1. 2010/11/28 CGAL : Computational Geometry Librry
  2. 2010/06/18 Iterators
  3. 2009/05/06 [TMP] chapter 2
  4. 2008/11/28 간단한 TMP 계산기
  5. 2008/02/29 C++ 과 객체지향
http://www.cgal.org/

C++ 기반의 계산기하 라이브러리. 전에 컴과 졸업논문 쓰면서 했던게 이쪽 관련된거라 그때 한번 찾아보고 잊고 있었다. 전반적으로는 C++로 아주 잘 짜여진 수학 라이브러리이다. 소스도 공개되어 있으니 한번 분석해 보면 큰 도움이 될듯.
저작자 표시
Posted by CECRI

Iterators

Programming/C/C++ 2010/06/18 17:44
Boost Graph 라이브러리(BGL)와 STL을 사용하면서 느끼는건데...

정말 참 좋긴 한데..

정말 좋은데 ㅋㅋ

근데 사용하기가 쉽지많은 않다.

STL은 제공하는것만 사용하려면 쉬운데(typedef만 좀 해 주면) 

내가 만든 클래스도 iterator를 직접 제공하려고 하는데 이게 STL의 iterator랑 호환되게 하려면

typedef도 좀 해 줘야 하고 operator 오버로딩도 좀 해 줘야 하고

특히 copy같은 algorithm 헤더에 있는 녀석들이 사용하게 하려면

뭔가 추가할게 많다 ㅠㅠ

BGL은 사용하기는 좋은데 descriptor랑 iterator가 막 섞여서 다 까먹고 다시 보려니 

애먹고 있다. 근데 descriptor라는 발상은 좋은데 뭔가 직관적이지는 않다.

그래서 프로그램 짜다 보면 사용자층은 좀더 직관적으로 사용 할 수 있고 추상적인건 숨기게 하려니

코딩량이 좀 많아지는듯.

저작자 표시
Posted by CECRI
C++의 템플릿 기능을 최대한 이용해서, 컴파일 시간에 작동되는 프로그램을 만드는 Template Meta Programming은 실행시간의 값 같은 것을 이용하지 않고, 컴파일 시간에 확정되는 개체처럼 이용한다. 이러한, 컴파일 시간에 다룰 수 있는 개체를 메타자료(metadata)라고 한다. 메타자료는 크게 형식메타자료(Type)와 비형식(Non-type) 메타자료로 나눌 수 있다. 비형식 메타자료는 컴파일 시간 상수값을 의미하고, 형식 메타자료는 컴파일 시간에 확정되는 클래스(class of struct)를 의미한다.

이런 컴파일 시간 개체들도 런타임의 값을 이용하는 함수처럼, 컴파일 시간에 확정되는 함수같은것이 있다. 이런 함수를 메타함수(metafunction)이라고 한다. 보통, boost의 MPL에서는 메타함수는 return값을 가지는 대신 메타함수<인자>::type을 반환값으로 쓴다. 다음과 같은 것이 메타함수의 예이다.

template<class T, class R, class X>
struct composit
{
    typedef typename T::template apply<R::template apply<X>::type >::type type;
}


메타함수는 인자(템플릿의 인자)로 주어진 클래스의 가능한 프로토콜(위의 예에서는 R이 template apply<X>를 가지고 있을것) 로 실행여부가 결정된다. 같은 프로토콜을 가지고 있으면 어떤 클래스라도 인자로 쓰일 수 있다. 즉 TMP의 다형성이 구현되는 원리이다. 이것은 비단 TMP만 그런것이 아니고, 모든 템플릿 기반의 함수들의 특징이다. boost의 graph라이브러리는 이런 특징을 정말 잘 이용하고 있다.

그러면 이제 Boost Type Traits 라이브러리에 대해 알아보자. 이 Type Traits 라이브러리는 표준STL에 있는 라이브러리와 비슷하지만, 한 클래스에 여러 정보를 담은 Blob(일종의 anti-pattern이다)를 없애고 훨씬 깔끔한 형태의 메타함수라는 점이 다르다. 자세한 내용은 http://www.boost.org/doc/libs/1_39_0/libs/type_traits/doc/html/index.html
이것을 보자.

저작자 표시
Posted by CECRI

C++의 또다른 매력 TMP


#include <iostream>
//TMP
template <bool cond, typename T1, typename T2> struct IF{};
template <typename T1, typename T2>
struct IF<false, T1, T2>{
 typedef T2 type;
};
template <typename T1, typename T2>
struct IF<true, T1, T2>{
 typedef T1 type;
};
template <typename T, typename U>
struct Typelist{
 typedef T hd;
 typedef U tl;
};
struct NullType{};
template<int n>
struct NUM{
 enum {val=n};
};
template<typename expr1, typename expr2>
struct PLUS{
 enum {val=expr1::val+expr2::val};
};
template<typename expr1, typename expr2>
struct MINUS{
 enum {val=expr1::val-expr2::val};
};
template<typename expr1, typename expr2>
struct MULT{
 enum {val=expr1::val*expr2::val};
};
template <typename exprlist>
struct MAX{
 enum {val=IF<(exprlist::hd::val > MAX<typename exprlist::tl>::val),
  typename exprlist::hd,
  MAX<typename exprlist::tl> >::type::val};
};
template<>
struct MAX<NullType>{
 enum {val=0};
};
int main(){
 std::cout <<
  PLUS<
   NUM<10>,
   MAX<
    Typelist<
     NUM<20>,
     Typelist<NUM<10>, NullType >
     >
    >
   >::val;
 return 0;
}

사실은 프로그래밍 원리의 nML숙제를 TMP로 구현한것.
저작자 표시
Posted by CECRI
사실 C++에서 객체지향은 그렇게 까지 큰 부분을 차지하고 있지는 않다. 스캇 마이어스 형님의 EC++에서는 C++은 절차형 언어, 객체지향형 언어, 제네릭 프로그래밍, STL이라는 네가지 부분으로 나눌 수 있다고 한다. 사실 STL은 라이브러리일 뿐이지만, 그 자체만으로도 엄청난 성능을 자랑한다. 웬만한 알고리즘과 자료구조는 전부 있으니 STL을 잘 아는 사람이 짠 수치계산이나 통계같은것의 코드는 전부 STL만 쓰여서 그냥 STL코드라고 불러도 될정도니 그렇게 포함시킨것 같다.

C++에서 객체지향은 그것을 이루는 네가지 구성요소중 한가지에 지나지 않는다. 여기서 자바와의 차이점이 발생한다. 하지만 이로 인해 생기는 오해가 C++을 java보다 못하다고 생각하는것이다.

많은 사람들이 C++의 객체지향정도가 많이 낮다고 한다. 이것에 대해서는 나도 어느정도 동의하는 편이다. 하지만 이것을 가지고 C++을 깍아내리는건 바람직하지 못하다. 여러 라이브러리나 이런것이 비 객체지향적으로 설계되어 있지만 그 이유는, 어느 경우는 템플릿을 쓰는것이 재사용성이나 간결함을 객체지향을 쓰는것보다 훨씬 잘 구현할 수 있기 때문이다.

C++에서 자바의 Object같은것이 없는 이유는 그런것을 통해 클래스 계층구조를 만듬으로써 잃는 성능상의 이점이 얻는것보다 많다고 느꼈기 때문일 것이다. 사실 Object같은건 프레임워크에서 구현할수 있는 것이고(MFC의 CObject가 그렇다) 보통의 경우 그것을 쓰지 않아도 충분히 코드를 만들 수 있고, 필요한 경우에도 템플릿 같은것을 쓰는 경우가 더 효율적일때가 많다.

사실 객체지향을 배우기에는 C++은 별로 바람직하지 못하다. C++의 원래 목적은 뛰어난 프로그래머에게 강력한 툴을 제공하기 위한것이라고 한다. 사실 C++의 복잡한 문법과 템플릿의 능력같은것을 보면 그 말이 틀리지는 않은 것 같다. 처음 객체지향을 배우는 사람이 C++의 방대한 문법을 본다면 꽤나 암담할 것이다.

그리고 많은 사람들이 JAVA를 객체지향적이라고 하지만, 자바의 객체지향은 C++의 부분집합이라는 느낌이 강하다. 물론 레퍼런스나 가비지 컬렉팅 같은것은 C++과의 뚜렷한 차별성을 주지만, 기본형과 객체의 구분과(오토박싱이 있긴 하지만 그래도 다른것은 다른것이다) '.'연산자로 메쏘드에 접근하는것은 사실 완벽한 객체지향이라는 smalltalk에 비추어 보면 그 정도가 모자란다. 사실 자바가 쓰기가 편하고 간결한것은 부정할수 없는 사실이다. 하지만 그 이유가 객체지향을 완벽히 구현했기 때문이 아니라, 사용자에 맞추어 개발된 언어기 때문이라는것이 내 생각이다.

smalltalk, ObjectC같은 메세지 기반으로 객체지향을 구현한 언어들을 보면 놀랄만큼 유연하다. smalltalk는 객체지향이 언어에 완벽히 내제되어있다(C++처럼 C에 문법을 추가해서 구현한 객체지향과 다르다는 이야기이다). 레퍼런스는 어느 타입이나 가리키고 메쏘드 호출은 메세지를 보내는것으로 대신한다. 가상함수나 이런것으로 구현된 오버라이딩이 아니라 메세지 처리기만 바꾸는 방식이다. 하지만 별로 인기가 없는것은 그만한 메리트가 없다는 것이겠지.

사실 WIN32API도 메세지 기반으로 C에서 객체지향을 구현하기는 했다. 하지만 언어가 아닌 관계로 언어의 문법 대신, 여러가지 API함수들을 통해 객체지향을 구현한다. 따라서 그닥 쓰기 쉽지가 않다. 객체지향적이긴 하지만 쓰다 보면 MFC가 왜 나왔는지 알수 있다.

다시 C++로 돌아오면 C++에서는 객체지향을 강제하는것이 하나도 없다. 라이브러리가 특별히 객체를 요구하지도 않는다. 그냥 함수객체같은것은 함수 포인터면 된다. 하지만 이것이 다른 방향의 객체지향을 만든다. smalltalk가 기본형과 객체 구분없이 레퍼런스로 가리킨다면, C++은 객체를 아예 기본형처럼 만든다. 객체는 수치형이 될수도 있고, 그냥 우리가 아는 그냥 객체일수도 있고, 아니면 함수객체같은것 일수도 있다.

사실 C++이 완전히 이렇지는 않다. 객체형을 받을때는 const T&로 받고 기본형은 그냥 값에의한 호출로 받기 때문에 차이점이 아예 없는것은 아니다. 하지만 제네릭 알로리즘 같은것은 C++의 이런 부분을 남김없이 사용할수록 되어 있다. 대충 알고리즘에서 사용하는 연산자들만 지원하면 어느 타입이든 전부 된다.

JAVA에서는 이런것을 따라하기 위해 객체지향적인 방법을 사용한다. T Max<T implements Comparable>(T[]) 같은 식이다. 하지만 이런것에서 T는 레퍼런스로 한정되어 있다. 기본형은 오토박싱을 써야 하고, 이런 제네릭은 TMP같은것도 불가능하다. 구현 자체도 JAVA에서는 T에 대해 compare메쏘드를 호출하는 식으로 비교한다. C++에서는 >연산자이다. 연산자 오버로딩의 강력함이다. 결국 함수 호출이 되지만 기본형에서도 잘 작동하고 무엇보다도 이런것을 통해 가벼워진다. 이런 식으로 C++은 객체지향을 포기하지만 강력함을 포기하지는 않는다.

사실 C++은 사용하기 어렵다. C++찬양을 하던 나도 별로 쓰고 싶지 않은 경우가 많다. 메모리관리를 직접 해야 하는건 정말 성가시다. java에서는 별로 필요 없는 pimpl 관용구를 써야 할때도 많다. 하지만 그래도 자바에서는 느낄수 없는 STL이나 템플릿의 강력함, 연산자 오버로딩, 스택에 쌓이는 객체 등은 정말 색다른 매력이다. 특히 자바에서 펑펑 낭비해가면서 쓰던 메모리를 C++로 돌아오면 조심조심 쓰는 그런 이중적인 모습도 발견할때 마다 웃게 된다 ㅎㅎ. 뭔가 java에서는 인간적 느낌이 별로 안느껴 지는듯.
Posted by CECRI