ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 전문가를 위한 C++ 정리(2)
    @ 16. 1 ~ 17. 1/C++ 2015. 4. 13. 00:15

     

    38. 유니폼 초기화! C++ 11

    객체 생성시 생성자 매개변수 전달시..

    A a(10, 20); 이렇게 하는걸

    A a{10,10}; 이렇게 괄호를 대괄호로 하면 좋다. 왜냐면..음..

    stl컨테이너에도 이용할 수 있으..

    vector<int> myvec;

    myvec.push_back(1);

    myvec.push_back(2);

    이렇게 하는걸.. 유니폼 초기화를! 딱!

    vector<int> myvec={1,2,3}; 또는 = 빼고 해도됨..

    이렇게 딱..

    동적 할당 배열ㅇ도..int* parray=new int[4]{1,2,3,4};

    생성자 초기화  목록에서 멤버 배열 초기화 할떄도.>!

    public:
    int marray[4];

    A() : marray{1,2,3,4} {}

    딱! 아우 헷갈려..

     

    39. 익셉션에서 타입이 const인지 아닌지 구분하지 않는다.

    즉, 다음의 라인은 A 타입이기만 하면 매치됨.

    catch(const A& a)

    catch(A& a)

     

    39-1. throw 리스트는 그냥...참고

    근데..리스트는 무시하고 던질수도 있어....근데..catch로 못받고 에러뜨고 종료되..참고!

    템플릿 함수 메서드에서는 지정을 못해 ㅎㅎ 어떤 타입이 될지 모르잖아 ㅎ

    함수선언/정의 둘다 해야함.

    void a() throw(무엇을 던질까 객체?); {}

     

    40. 클래스 계층에 맞춘 익셉션 처리!

    다형성에 의존해 익셉션을 캐치할때 참조또는 포인터형으로 받아라 위에처럼..그래야지 슬라이싱이 발생하지 않음..(발생하면 하위클래스의 세부정보를 잃지요..)

    catch(다형성~ 상속~)

    물론 catch의 순서도 세부적에서 포괄적으로 해야..정수기처럼 걸러짐..

     

    41. 컼스텁 익셉션 클래스 만들기

    1) 표준 exception 클래스를 직간접적으로 상속받는것이 편하다. 왜냐면 모든 익셉션이 exception클래스의 서브클래스라 가정할 수 있기 때문에..다형성을 활용하기 쉬움.

    2) 익셉션 클래스를 만들떄 주의사항으로 어떤 객체나 값이 익셉션으로 던져질때 반드시 복제가 수반된다. 즉 복제 생성자를 통해 새로운 객체가 기존 객체로부터 만들어진다. 그래서 복제할 수 있도록 만들어야하고 혹시 동적 할당 메모리가 있다면 알지? 복제 생성자 대입연산자 구현해야하는것..

     

    42. 익셉션간 스택 되돌림시 메모리 누수..

    throw 걸리면 막 뒤로가서 catch로 가잖냐..그러면 그 뒤에 있는거 실행이 하나도 안되잖냐..

    근데 그 뒤에 delete 잇으면? 안되는거라고..누수

    그래서 스마트 포인터 쓰라고 ㅋ

     

    43. 생성자에서 발생하는 에러

    익셉션을 배우지 못하면 생성자에서 발생하는 에러처리가 문제다.

    리턴값이 없으므로 애먹는다..(뭐..)플래그 멤버 변수를 두어 표기할수는 있지만..

    익셉션이 훨씬 낫다. 왜냐면 익셉션 던지는건 가능하니까..

    근데 익셉션으로 나가게 되면 해당 객체의 소멸자가 불릴 기회가 없다는게..

    그래서 생성자를 벗어나기전 할당 중이던 메모리 및 리소스들 해제해야한다.

    그리고 throw bad_alloc(); //

    ? 상속에서는요? 슈퍼클래스의 생성자는 서브클래스의 생성자보다 먼저 실행된다.

    서브 클래스의 생성자가 익셉션을 던지면 슈퍼클래스에서 할당받은 리소스 해제는?

    걱정마라 정상적으로 생성자가 생기면 소멸자도 반응하니까..

     

    44. 템플릿 클래스는 다른 일반 클래스와 달리 구현부도 헤더파일에 있어야함.

     

    45. STL 컨테이너 용어들..

     구분

     내용

    장점(빠름)

    단점(느림)

    비고 

    순차

    컨테이너

    (반복자지원)

     vector

    직접 빨리 접근 시

    배열을 사용할만한곳

    마지막 인덱스 삽입, 삭제시

    자주 삽입 / 삭제 시

    bool형 제공vector<bool>

    bitset과 차이점 존재

     list(이중연결)

    특정위치 삽입 / 삭제시

    찾고 접근 시 

     

     deque(양방향)

    탐색 / 색인 시

    앞, 뒤에 항목 삽입 / 삭제 시 

    중간에 삽입 / 삭제 시 

     별로 활용할 일 없음

    C++11 array

    오버헤드 없음(고정되어있음)

    반복자 제공 

    삽입 / 삭제 미지원

    크기가 고정됨

    (기능은 vector와 같음)

    C++11 forward_list

    (단방향 리스트)

    list보다는 메모리 적제 차지

    list와 같음 

     

    컨테이너

    어댑터

    queue(선입선출)

    삽입 / 삭제 시 

     

    실세계 선착순 개념 

    priority_queue

     

     queue보다 삽입, 삭제가 느림

    queue에 우선순위 적용우선순위가 같을시 선입선출

    stack

     삽입 / 삭제 시

     최근에 삽입된것만 삭제가능

    후입선출(선입후출)

    연관

    컨테이너

    (반복자지원)

    set

    (균형 이진트리)

     삽입 / 삭제(vector보다 빠름)

     탐색 / 색인(list보다 빠름)

     삽입 / 삭제(list보단 느림) 

     탐색 / 색인(vector보단 느림)

    값이 중복존재 x 

    (중복허용 multiset)

    각 작업 모두 만족해야할시 사용

    map

    (균형 이진트리)

     (이외 set과 같음) 

    키와 값을 같이 저장

    multimap도 있음

    특수

    컨테이너 

    bitset 

    크기에 제약없음

    (단, bitset<N> 선언해도 N비트보다는 조금큼)

    삽입 / 삭제구조가 없음

    반복자 지원하지 않음

    비트플래그

    (& | ^ ~ << >> ) 

     

    46. 컨테이너에 포인터를 저장해야한다면 스마트 포인터를 이용해라 (shared_ptr)

     

    47. 컨테이너에 저장되는 항목이 가져야할 요건..

     - 복제 생성자, 대입연산자, 소멸자, 디폴트 생성자, operator==, operator< 이정도..? 왜냐면..

     - STL에서는 항목에 대한 복제 생성자와 대입 연산자를 자주 호출하기 때문에 그렇다..

     

    48. 순차컨테이너

    48.1.1. vector

    다음과 같이 heap에도 생성된다.

    vector<클래스>* ele=new vector<클래스>(10);

    delete ele;

    아니면

    스마트 포인터로.. shared_ptr<vector<클래스>> ele(new vector<클래스>(10));

     

    48.1.2. vector의 복제와 대입

    vector클래스의 복제 및 대입 연산자는 저장된 항목들에 대해 깊은 복제를 하도록 구현되어 있다.

    이때문에 vector객체를 전달할때 참조형 또는 const 참조형으로 전달...

    assing() 현재 저장된 항목을 모두 삭제하고 개수에 상관없이 새로운 항목 추가..

    예) vector<int> int(10,0) //값 0 인 int 항목 10개

          int.assign(5,100); //값 100인 int항목 5개

     

    48.1.3 vector간 비교

    커스텀 클래스를 저장하는 vector의 경우 비교연산자(==, < , !=  > <= ..등)을 두 vector객체간에 사용해야한다면..반드시 이들 연산자를 커스텀 클래스에서 오버로딩하여 구현해야한다..

     

    48.1.4. vector 반복자 관련

    - 반복자를 사용시 iter ++사후증가보다 ++iter사전증가가 더 빠르다..약간..

    - 반복자를 사용하는 이유는 컨테이너 임의의 위치에 삽입 / 삭제가 가능하다

    - stl 알고리즘을 사용할 수 있다. 인덱스 접근보다 종종 더 빠르다..

    *반개방범위 : 시작 반복자로 지정된 위치는 포함되지만 종료 반복자가 지정한 위치는 포함되지 않는다.

     - 새로운 항목을 삽입, 삭제하면 변경된 공간에 맞춰서 움직인다 하지만 반복자는 앞이나 뒤로 옮겨지지 않는다

       (더이상 유효하지 않음 추가로 메모리 재할당시에도 포함!)

     * 반복자 앞에서는 삽입 / 삭제가 일어나면 반복자를 위치를 재할당해야하는데..뒤에서 삽입삭제가 일어나면 괜찮을듯..?메모리 할당이 일어나면 망하지만..(추측일뿐 확인못함)

     

    48.2. vector<bool>

    bitset보다는 덜 풍부한 비트필드 이다.

    filp() 메서드를 활용하여 비트 값을 반전시킬 수 있고 모든 비트 또는 특정 비트만 반전시킬수 있음.(operator[])

    ..그냥 bitset써라..

     

    48.3. list

    operator[] 지원을 안함..랜덤액세스라 불리우는데 지원안한다고..

    그래서 개별 항목에 접근하려면 반복자 이용해야해

    그리고 ++ -- 이런걸되는데.. + n -n 이런거 안됨...(위치점프..)

     

    48. 4 array 와 forward_list (단방향 리스트)

    * 단방향 리스트의 경우 반복자가 한쪽으로만 이동..이때문에 특정 항목에 접근해야 한다면 반드시 이전 항목에 접근..일반 list는 마지막 항목만 end()가 개방형 범위였는데 단방향의 경우 시작 항목도 개방형 범위로 제공됨.

     

    49. 컨테이너 어댑터

    49.1. queue

    정의부 : template<class T, class Container=deque<T>> class queue;

    //첫번째 매개변수는 queue에 저장한 데이터 T타입

    //두번째 매개변수는 queue가 감쌀 컨테이너 타입

    list도 사용가능하지만 대부분 그냥 deque사용함.

     

    49.2 priority_queue

    정의부 : template<class T> class Container=vector<T>, class Compare=less<T>>;

    //디폴트가 vector이지만 deque도 가능 함. 근데 list는 안됨

    //less는 T타입의 두 객체를 operator<로 비교할수 있게 해줌. 근데 이게 문제인게..int char 같은건 operator<가 문제가 없는데 클래스나 구조체를 쓴다면.. bool operator<(const 좌변&, const& 우변)으로 재정의해야함..

    (디폴트 비교 클래스를 이용할때는 사용하는 타입에 operator<가 정의되야함)

     

    49.3 stack

    선입후출이라는 점만 틀리고 queue와 거의 같다

    tempalte<class T, class Container=deque<T>>class stack;

    // vector, list, deque중 어느것이나 사용가능함 기본 deque

     

     

    50. 연관 컨테이너

    순차 컨테이너와 달리 항목들을 선형으로 저장하지 않음! 대신 키와 값을 짝을 지어서 저장!

    * pair클래스(연관 컨테이너 살펴보기전 봐야함..)

    서로 다른 타입의 두 값을 그룹핑할 수 있는 클래스

    pair 객체의 생성 편의를 위해 템플릿 함수 make_pair()를 제공

    pair<int, int> aPair=make_pair(5,10);

    auto aSecondPair=make_pair(5,10);

    pair<int, int> aPair3(1,10);

    다 같음..또는 pair를 매개변수로 하는곳에 mAccount.insert(make_pair(10, 객체)) 이런식..?(insert는 map insert) // make_pair() 함수는 즉석에서 pair를 생성해 반환한다

    중요 : 일반적인 포인터 타입을 pair의 멤버로 사용하면 위험..복제 생성자와 대입연산자는 얕은 복제만 하기때문..그런데 스마트 포인터는 안전 shared_ptr !

    value_type과 달리 make_pair()를 사용시 임시 pair가 생성되면서 속도 저하현상이 발생한다.

    map의 data가 단순 데이터가 아닌경우 상황에 따라 속도차이가 다르다~

    50.1 map

    레드-블랙 트리 같은 균형 트리의 형태로 구현됨.

    디폴트 비교 클래스를 이용할때는 사용하는 키 타입에 operator<가 정의되어있으면 된다. 없으면? 만들어야지

    그리고 저장시 중복은 안됨.

    insert() 메서드 사용시 반복자(first)와 bool 값(second)가 pair로 리턴되는데..

    성공시 : 반복자(새로 삽인된 항목위치), bool(true)

    실패시 : 반복자(해당 키를 가지는 기존에 저장된 항목), bool(false)

     

    non-const 반복자를 이용해 항목의 값을 변경할 수 있다.

    하지만 키는 못바꿈..아무리 non-const 여도..잘봐라 원형이 뭔지.(const) 그리고 키가 변경되면 정렬상태가

    깨지므로..

     

    찾을시 찾으려는 항목의 키를 알고 있다면 operator[] 를 이용하는게 더 편리..(데이터 값을 바로 참조형으로 리턴)

    만약 모른다면? find() 메서드 활용

     

     


    9.55 초기화 리스트 빼먹음..

    9.56 ~ 9.8 요약까지 넘김..

    10.5 흔한 에러처리 관련문제

    10.5.1 메모리 할당에러(new)

    new 연산자에서 메모리할당 할 수 없을때 <new>헤더에 정의된 bad_alloc익셉션을 발생시킴..

    그래서 catch만 잘하라고..근데 반드시 bad_alloc 객체를 받으라고..cath(const bad_alloc& e);

    10.5.3 생성자를 위한 함수 try 블록

    10.5.1.1 익셉션 없는 new

    10.5.2 생성자에서 발생하는 에러

    10.5.3 생성자를 위한 함수 try 블록

    10.5.4 소멸자에서의 에러

    12.3.1.2 스레드의 안정선을 위한 동기화 기능??동기화 메커니즘?

    '@ 16. 1 ~ 17. 1 > C++' 카테고리의 다른 글

    전문가를 위한 C++ 정리(4)  (0) 2015.05.01
    전문가를 위한 C++ 정리(3)  (0) 2015.04.21
    예외처리  (0) 2015.03.28
    전문가를 위한 C++ 정리(1)  (0) 2015.03.28
    멤버 함수가 객체 자신을 리턴하는 경우  (1) 2014.10.27
Designed by Tistory.