본문 바로가기

프로그래밍/C++

생성자 제작 시 제한사항 생성자 제작시 제한사항 생성자는 반환값을 설정할 수 없습니다. 아무래도 생성이라는 것이 항상 되면 좋겠지만, 여러가지 경우에 있어 생성이 실패하는 경우도 많습니다. 이럴 경우 다른 함수의 경우 실패를 반환하면 되겠지만, 생성자의 경우에는 예외를 던질 수밖에 없습니다. 예외라는 것이 처리하기도 불편하고 (try-catch 구문) 그 자체의 비중도 좀 되고 예외에 안전한 코드가 아니게 됩니다. 예를 들면, COpenFile::COpenFile( const string &filename ) { if( false == m_is.open( filename.c_str() ) ) throw "break!!"; } 이런식의 문법밖에는 쓸 수가 없죠. 생성자에 인자를 넣을 수 없는 경우가 있습니다. 이것도 꽤 제한사항이.. 더보기
한 스트림을 다른 스트림으로 연결하기 한 스트림을 다른 스트림으로 연결하기 배경 C++에서 기본적으로 전역으로 제공하는 스트림은 네 개가 있습니다. 바로 cin, cout, cerr, clog 입니다. ( clog는 C++에서 처음 생긴 것으로 알고 있습니다. 긴 입력을 받아들이는 데 좋다고 합니다. ) 하지만 윈도우 프로그래밍과 같이 콘솔창을 쓰지 않는 프로그램을 짤 떄에는 저 객체들은 쓸모없어집니다. 그럴 떄에 저 스트림을 파일로 돌리면 저 객체를 다시 이용할 수 있게 됩니다. 특히 에러로그 등을 남길 때 쓸만하죠. 또한 스트림 형태와 호환되는 객체를 만들었다면 그곳으로 연결해줄 수도 있습니다. 이 글에서는 스트림을 다른 스트림과 연결하는 방법에 대해서 소개하려고 합니다. 방법 C++ 스트림에서는 다른 스트림과 엮어주는 것을 두 가지를 .. 더보기
[C++] 헤더파일을 나누어 은닉화 구현하기 [C++] 헤더파일을 나누어 은닉화 구현하기 배경 이 내용은 모듈화에 대한 생각으로부터 시작합니다. 저는 개인적으로 어떤 코드 조각이 큼지막한 것을 꽤 싫어합니다. 특히 헤더가 지저분한 것은 딱 질색입니다. 일반적으로 헤더는 사용자가 쓰기에 일목요연하고 정리된 모습을 보여줘야 한다고 생각합니다. 그러기 위해서는 필요에 의한 것(객체 혹은 함수)들과 사용자에게 제공하는 것들을 구분할 필요가 있습니다. 이에 관하여 흥미로운 내용을 [The C++ Programming Language]에서 발견하였고 그 내용을 간단히 정리하고자 합니다. 사용자와 구현자 일반적으로 어떠한 코드 조각(Code segmant)를 구현하였을 때, 그 코드 조각이 필요한 사람들은 대부분 사용자와 구현자 로 구분할 수 있습니다. 구현자.. 더보기
[C++] Insertion Sequance( std::vector, ... ) 내용 삽입시 치환을 통해 값을 삽입합니다. 즉, 생성자가 불려져서는 안 되는 객체를 저장한다면 무조건 포인터로 저장해야합니다. 다음은 push_back을 쫓아간 내용입니다. 임의로 필요한 부분만 잘라다 붙였습니다. void push_back(const _Ty& _Val) {// insert element at end insert(end(), _Val); } iterator insert(iterator _Where, const _Ty& _Val) {// insert _Val at _Where _Insert_n(_Where, (size_type)1, _Val); } void _Insert_n(iterator _Where, size_type _Count, const _Ty& _Val) {// insert _C.. 더보기
[C++] 선언 없이 단 한 번만 실행되기 무언가 프로그램이 시작하고 끝날 때까지 단 한 번만 실행되었으면 좋겠다. 사실 이것은 단일체(Singleton)의 목적이라고 할 수 있습니다. 헌데, 그것과는 오묘히 다릅니다. 단일체는 단 한 개의 객체를 보장받기 위해서 일반적으로 사용합니다. 지금 말하고자 하는 것은 단 한 개의 객체가 아니라 단 한 번만 실행되는 무엇입니다ㅣ. 객체를 이용할 것도 아니고 그저 프로세스 전체에서 단 하나를 실행시키는 그 무엇 말입니다. 이미 알려진 방법이 있을 수도 있겠는데 제가 생각해낸 방법은 다음과 같습니다. 이것은 Singleton Pattern에 나온 정의입니다. class Singleton{ public: static Singleton getInstance(){ return selfInstance; } priv.. 더보기
단일체 Design Pattern에서 이야기하는 단일체의 기본형은 class Singleton{ public: static Singleton getInstance(){ return selfInstance; } private: SIngleton(); static Singleton *selfInstance = new Singleton(); }; 였다. 요새 가능하면 모든 프로그램을 정적으로 만들려던 나에게 저 방식은 C++에서는 무조건 메모리 해제가 필요한 상황이었고, 게다가 생성은 명시적으로 안 해주면서 해제의 책임은 지워야하는 정말 맘에 안 드는 방식이었다. 이에 고민하던 중 승중이가 알려준 방식이 있었으니 바로 이것이다. class Singleton{ public: static Singleton &getIns.. 더보기
Java의 Package 자바에서는 public, protected, private 등의 액세스 제어가 아무것도 붙어있지 않은 생성자나 메소드는 같은 패키지 내의 클래스에서만 이용할 수 있습니다. package의 의미는 namespace 정도라고 생각했는데 여기서는 public과 private의 중간단계의 접근 권한을 설정할 수도 있군요. 더보기
[C++]예외 처리 예외는 해당 클래스가 폐기되어야 할 에러에만 발생시키도록 하고 나머지 에러는 반환값으로 처리한다. 더보기
[C++]클래스와 구조체 C++로 넘어오면서 struct와 class는 그 역할이 매우 동등해졌다. 실제 동작면에서는 그렇다. ( 아니 확인해보지는 못했다. C와 같이 struct의 변수들은 주소공간에 차례차례 배치되어 있는지 ? ) 단지 차이가 있다면 struct는 기본적으로 필드가 public이고 class는 기본적으로 필드가 private랄까. 아무래도 C 스타일에서 주로 쓰던 struct의 형태로 C++에서도 사용하게 되었다. 필드마다 Get, Set을 사용하기 싫을 때 struct를 애용하였다. struct에는 별다른 함수를 지니려고 하지 않았고, 다만 생성자와 소멸자는 간간히 쓰는 편이었다. 좀 필드가 많아질 가능성이 보이면 class로 바꾸는 행태를 보이곤 했다. 오늘 하나의 클래스에 구조체를 만들고 구조체에 기능을.. 더보기
여기서 교과서적인 이야기 하나. 여기에서 교과서적인 이야기를 하나 하고 넘어가야 할 것 같다. 루프 안에서 항상 선행 증가(++c)를 사용하는 것이 좋은 이유는 무엇일까? 효율성 때문이라는 것이 정답이다. 후행 증가 연산자(c++)는 변수의 이전 값을 돌려주므로 이전 값을 담을 임시적인 변수를 만들고 파괴하는 과정이 일어나게 된다. 후행 증가로도 선행 증가와 동일한 방식의 루프를 만드는 것이 가능하지만, 후행 증가를 사용할 특별한 이유(위의 예제에 나온 것 등)가 없다면 항상 선행 증가 또는 성행 감소 연산자를 사용하는 것이 바람직하다. - Mark Deloura, Game Programming Gems, 정보문화사, 2001. ... 생각해보면 너무 당연한 이야기인데.. 저런 이유일 것이라고는 생각지 못했다. 항상 후행 증가 연산자만.. 더보기