Introduction
안녕하세요, 알고리즘 엔지니어 YoungJ입니다. 근 2년간 SLAM을 비롯한 Computer Vision 스터디를 진행하며 많은 알고리즘들을 직접 구현 및 실험을 해봤는데요. 저는 개인적으로 Python을 통해 실험 및 데모 개발을 진행하고, C++로 성능 최적화 및 프로젝트에 코드를 추가하는 과정을 선호합니다.
이 과정마다 C++ 개발 단계가 저에게는 bottleneck으로 작용한다는 것을 발견했습니다. 그럴 때마다 C++를 더 잘하고 싶다는 욕망이 커져만 갔고, 이번 기회에 본격적으로 깊게 공부를 해보고자 합니다. 학부 과정 이후로 진득하게 서적과 여러 레퍼런스들을 찾아보는 과정이 처음이라 많이 낯설지만 조급해하지 않고 차근차근 나아가려 합니다.
C++를 잘하는 기준은 뭘까?
그렇다면 C++를 잘한다는 기준은 무엇일까요? 나아가 C++스러운 코딩 스타일은 무엇일까요? 이를 알기 위해서는 우선 C와의 차이점을 명확하게 짚고 넘어가야 합니다.
아무도 관심 없겠지만 고백하자면 저는 둘 간의 차이점을 잘 모르며 사용했었습니다. 그냥 단순히 struct
와 class
의 syntax 차이가 존재하나, 기능적으로는 큰 차별점을 느끼지는 못했습니다. 물론 상속을 필두로 한 객체 지향 프로그래밍의 철학과 개념은 알고 있었으나, 알고리즘 개발 및 연구를 위한 개인 혹은 소규모 팀 단위 개발에서 OOP까지 고려해 개발하기란 쉽지 않았습니다.
실제로 C++은 초기에는 C with classses로 스스로를 정의내릴 정도로 객체 개념을 추가한 C로 봐도 무방했습니다. C++ 98이 주력이던 시대는 이런 개념이 지배적이었죠. 그러다 C++ 11에서 천지개벽 수준의 대격변이 있었고, 흔히들 이 시점부터 modern C++라고 부릅니다. 우리는 여기에 주목해야 하는데요. 저는 이 시점을 C++가 C로부터 독립해 완전히 다른 언어로 자리매김하는 시기라고 생각합니다.
C++을 가르치는 사람들 간에도 차이가 존재하는 이유가 여기에 있다고 생각하는데요. Python은 2.x와 3.x가 서로 다른 언어로 봐도 무방합니다. 그러나 C++은 이전 버전에 대한 호환이 모든 언어를 통틀어 상위권으로 봐도 괜찮을 정도로 호환성이 좋은 언어인데요. 이러한 장점이 한편으로는 진입 장벽을 높이는데 이바지했다고 개인적으로 생각합니다.
서론이 길었는데요. 결론적으로 C++을 잘한다는 기준은 여타 다른 언어와는 다른 접근이 필요하다고 생각합니다. 추가로 C++로 작성된 오픈 소스 코드를 이해하지 못한다고 해서 스스로를 C++ 벌레라고 생각하지는 말아주세요. 저는 그랬거든요여러분이 잘못한 게 아닙니다. 이 언어는 그럴 수밖에 없는 구조를 갖고 있습니다. 그러니 저처럼 자책하며 땅을 파고 들어가지는 않길 바랍니다.
C++을 하나의 언어로 봐야 하는가?
Python에는 Python만의 규칙이 있고, C를 효율적으로 짜기 위해서는 정해진 공식들이 있습니다. 그렇다면 C++ 에는 이와 같은 것들이 존재할까요? 놀랍게도 일관된 규칙을 C++에서 찾기란 하늘에 별 찾기와 같습니다. 이는 앞서 언급한 언어들과는 근본적으로 다른 점이 있기 때문인데요. 이제부터 C++은 단일 언어가 아니라 여러 언어들의 연합체로 이루어진 다중패러다임 프로그래밍 언어로(multiparadigm programming language) 접근해 봅시다.
이런 접근이 아주 어색하지는 않을 것입니다. 학교 선배나 조교, 혹은 교수님에게 C++의 정의에 대한 질문을 드리면 매우 다양한 답변을 얻을 수 있을 텐데요. 누군가는 절차적(procedural) 프로그래밍 언어로, 누군가는 객체 지향(objective oriented), 다른 이는 함수형(functional), 그리고 이외에도 일반화(generic), 메타 프로그래밍(meta-programming) 등이 답변으로 존재할 수 있습니다. 그러며 C언어의 정통을 계승한 절차 지향 프로그래밍이 최고라고 말하거나, 거대한 프로젝트를 유지 및 보수에 용이한 객체 지향 프로그래밍이 최고라고 덧붙이거나, 다 필요 없다 이제 패러다임은 함수형과 일반형이다 하는 부류 등이 싸우기 시작하며 혼돈의 카오스로 이어나갈 테죠. 과연 하나의 언어에 대한 정의가 가지각색인 게 정상일까요?
놀랍게도 C++에서는 정상임과 동시에 정답입니다. 어느 시점에 C++을 공부했는지, 어떤 스타일의 개발에 이를 사용했는지에 따라 프로그래밍 언어를 가지각색으로 정의 내릴 수 있습니다. C++은 그만큼 많은 기능을 제공하고, 이는 처음 접하는 사람들에게는 충분히 혼동을 줄 가능성도 존재합니다. C++은 상관관계가 있는 여러 하위 언어의 연합체로 보는 것이 타당하고, 서로 상관 관계가 있기에 다른 하위 언어의 스타일로 프로그래밍을 해도 문제없지만 최적화된 답은 아닐 것입니다. 이제부터는 C++ 이 제공하는 네 가지 하위 언어들을 간단하게나마 살펴보도록 하겠습니다.
Sublanguage of Cpp
- C style C++
우선 너무나 당연하게도(?) C++은 C 스타일의 프로그래밍을 지원합니다. 객체 지향을 추가한 C라는 그 근원에 충실하게 C의 모든 스타일을 계승합니다. 실제로 C++ 98을 표준으로 배운 프로그래머들은 이러한 접근법으로 코드를 작성하는 경우가 많습니다.
- OPP style C++
C에 객체 지향을 추가한 언어라는 본래의 의도에 충실한 스타일입니다. 클래스, 캡슐화, 상속, 다형성, 가상 함수 등 여기서부터는 C++ 만의 무언가 들이 추가되는 시점입니다. 학부 과정에서 고급 객체 지향 프로그래밍 등의 과목을 수강한다면, 여기에 해당하는 개념들을 배울 것입니다.
- Template style C++
C++의 일반화(generic) 프로그래밍에 해당하는 스타일입니다. 프로그래머들이 자기도 모르는 사이에 많이 접했지만, 손으로 직접 짠 경험은 극히 드문 스타일이라고 개인적으로 생각합니다.제가 그렇거든요많은 오픈 소스에서 캡슐화, 추상화를 위해 template style로 코드를 작성했지만, 그 내부를 들여다볼 일이 적은 일반적인 사용자들은 이를 체감하지는 못합니다.
그러나 우리가 잘 알지 못하는 것과는 별개로 템플릿의 강력함은 당시 꽤나 큰 충격이었고 이는 템플릿 메타프로그래밍(TMP)이라는 프로그래밍 스타일의 탄생으로까지 이어졌습니다. 이는 보편적인 C++ 세계와는 조금 다른 영역이니 꼭 알아야 할 필요는 없습니다.
- STL
이름에서 알 수 있듯이 STL(Standard Template Library)은 표준 템플릿 라이브러리입니다. 그러나 그 완성도와 범용성은 일반적으로 템플릿 프로그래밍 기반으로 작성된 오픈 소스들과 차이가 있는데요. Container, iterator, algorithm, function object 등 다양한 구조들이 복잡하고 치밀하게 얽혀있습니다. 안 쓰고 프로그래밍을 해도 문제는 없지만, 그 효율과 위력이 남다르니 꼭 한 번 접해보시길 바랍니다.
나는 과연 어떤 스타일의 C++을 쓰고 있을까?
위 내용들을 접한 이후 복잡하고 엉망이던 머릿속이 맑아지는 기분이 들었습니다. C++을 너무 못해서 오픈 소스들을 이해하지 못했던 것이 아니었구나. 다만 그 전부를 몰랐을 뿐이구나. 이런 생각이 들면서 그러면 앞으로는 다른 스타일의 C++도 공부하고 사용해보고 싶다는 생각이 들었습니다.
참고로 저는 스스로 C 스타일과 객체 지향 스타일의 C++ 만을 사용하고 있다고 생각합니다. 템플릿은 그 기능만 알고 있고 직접 사용한 경험은 손에 꼽습니다. 마지막으로 STL의 경우 그 효용성은 익히 알고 있지만, 찾아보기 귀찮다는 이유로(어이없지만) 사용 빈도가 높지는 않았습니다.
그래서 이번 시리즈는 기존에 알던 C, OOP 스타일의 C++ 방법론을 비롯한 굵직한 개념 정리 위주로 정리할 생각이며, 새로 본격적으로 공부할 템플릿, stl 스타일의 개념은 예제 코드 등 공부한 흔적들을 남길 생각입니다.
Reference
레퍼런스는 전문가를 위한 cpp, effective cpp, modern effective cpp, 씹어먹는 cpp 등을 참고했습니다.