나의 경우 주로 for문에서 후위증가를 사용했었고 타인의 코드를 볼 때 전위증가를 사용하는 사람이 있으면 그냥 스타일 차이인가 보다 하고 넘겼었는데 갑자기 궁금해져서 찾아보게 되었다. 전위증가와 후위증가의 차이는 결론적으로 전위증가가 더 효율적이다. for문내에서는 컴파일러가 전위증가를 사용하던 후위증가를 사용하던 별차이가 없다고는 하지만 실제로 list의 전위,후위 증가 연산자 오버라이딩 된 코드를 보면 전위연산자가 조금더 효율적인것 같다. _Self& operator++() _GLIBCXX_NOEXCEPT //전위증가 { _M_node = _M_node->_M_next; return *this; } _Self operator++(int) _GLIBCXX_NOEXCEPT //후위증가 { _Self __..
vector를 사용한 뒤 메모리를 해제해주기위해 보통 clear함수를 많이 호출한다. 그러나 clear함수는 vector에 저장된 값들은 제거되지만 vector에 할당 된 메모리는 삭제되지 않는다. 아래의 예를 보면 clear 함수 호출 후에도 capacity값이 남아 있음을 볼 수 있다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include #include using namespace std; int main(void) { vector vt; vt.push_back(10); vt.push_back(10); vt.push_back(10); vt.push_back(10); vt.push_back(10); vt.push_back(10); vt.clear(..
대부분의 경우 vector를 for문에 사용할 때 iterator를 사용하거나 초기화식을 int를 사용한다. iterator로 사용할 경우 문제없지만 초기화식 타입에 int를 사용할 경우 오버플로우를 발생할 수 있다. 왜냐하면 vector의 size는 정확히 말하면 signed int가 아니라 unsigned int 타입이기 때문이다. 따라서 이러한 버그가 발생하면 찾기도 힘드니 정확한 방법으로 vector를 사용하도록 한다. 예제 1234567891011121314151617181920#include #include using namespace std; int main(void) { vector vt; vt.push_back(10); vt.push_back(10); vt.push_back(10); vt..
STL size()함수 주의사항 STL에서 제공하는 size()함수의 리턴타입을 찾아보면 아래와 같이 부호가 없는 정수형으로 나와있다. std::size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int 따라서 size()함수를 통해 아래와 같은 코드를 작성하면 문제가 된다. for (int i=0; i < vt.size() - 1 ; i++) doSomething(); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include #include using namespace std; ..
Visitor Pattern (방문자 패턴)목적 객체의 속성과 처리(연산)를 분리함으로써 클래스를 수정하지 않고 새로운 연산을 추가할 수 있다. MVC패턴에서 Model과 View를 나눠 놓은것과 비슷하다. UML상에서 Element은 Model과 매핑되고 Visitor는 Controller에 매핑된다. Element에서 Visitor를 accept했을 자기 자신을 Visitor의 visit메소드로 전달 해주는 구조이다. 사용 시나리오 변수 a와 b를 가지고 있는 Element가 있다고 가정한다. Element의 수정없이 더하기 연산과 곱하기 연산을 추가한다. [Element] class Element { public: virtual ~Element(){}; virtual void accept(Visit..
State Pattern (상태 패턴)목적 객체(Context)가 가질 수 있는 (유한한)상태를 추상화하여 런타임에 상태를 유연하게 변경하도록 한다. UML상 전략패턴과 거의 동일하지만 실제로 다른점은 전략패턴의 경우 사용하는 쪽에서 직접 알고리즘을 교체하지만 상태패턴은 사용하는 쪽에서 내부의 상태가 어떻게 바뀌는지 모른다. FSM(Finite State Machine)을 구현하기에 적합한 패턴이다. 사용 시나리오 전구 상태를 표현하는 시스템이 있다. 전구의 상태는 켜짐과 꺼짐 두개가 존재하며 on/off 버튼을 통해 상태가 변한다. 꺼진 상태 -> on 버튼 -> 켜짐 -> on 버튼 -> 동작 안함 켜진 상태 -> off 버튼 -> 꺼짐 -> off 버튼 -> 동작 안함 [Context] class ..
Memento Pattern (메멘토 패턴) 목적 캡슐화를 위배하지 않은 채 객체의 내부 상태를 저장하고 되돌아올 수 있도록 한다. 사용 시나리오 텍스트 에디터를 개발중에 있다고 가정하자 텍스트 에디터에 ctrl Z입력시 이전에 입력했던 텍스트로 상태를 불러오는 기능을 추가한다. [Memento] class InputMemento { public: InputMemento(string& input) { this->input = input; } string getState() { return this->input; } private: string input; }; [Originator] class InputOriginator { public: void setCurrentInput(string input) {..
Mediator Pattern (중재자 패턴) 목적 각각의 객체들(colleague)끼리 서로를 직접 참조하지 않고 mediator(중재자)를 통해 메세지를 주고 받는다. 각각의 객체들은 서로에 대한 정보는 전혀 모르기 때문에 커플링이 느슨하게 한다. 사용 시나리오 스마트폰이 없던 시절 문자로 단체일정을 잡기 위해서는 아래의 그림과 같이 개개인에게 연락을 했어야 했다. 스마트폰의 등장이후로 단체톡방(Mediator)을 만들어서 메세지(일정)를 보내면 된다 [Mediator] class Meditator { public: virtual ~Meditator() {} void addColleague(Colleague* collegue) { this->collegues.push_back(collegue); } ..
Command Pattern (명령 패턴) 목적 Client가 어떤 기능에 대한 요청을 할 때 요청을 직접 호출하지 않고 요청자체를 캡슐화한다. 명령 패턴의 핵심은 연산을 실행하는 데 필요한 인터페이스를 선언해 놓은 Command 추상 클래스이다. Client입장에서는 필요한 구체화된 Command만 설정해주면 된다. 사용 시나리오 Iot 허브가 있고 허브에서 연결된 things를 제어한다고 가정한다. Iot허브는 Invoker가 되고 things는 Receiver가 된다. things 각각의 명령어를 command로 구체화 한다. 해당 예에서는 IoT기능이 있는 IotTV를 Command패턴을 통해 제어하는 예이다. [Receiver] class IotTV { //Receiver public: void..