블로그
전체 21#태그
- CPP
- C++
- EffetiveC++
- EffectiveC++
- UE4
- 알고리즘
- EffecitveC++
- 스타트업
- 요약
2022. 05. 31.
0
항목13 - 자원 관리에는 객체가 그만!
자원해제 delete는 왠만하면 소멸자서 실행하자.(스마트 포인터를 사용해 자동으로 소멸하게끔 해도 좋음) but, 스마트포인터나 trd::shared_ptr은 delete를 사용하지, delete[]를 사용하지 않는다. 동적배열을 사용하였을 경우 delete로는 모든 메모리를 초기화 시킬 수 없다..(에러도 안난다고 하니 조심하자) 자원해제를 일일이 하다보면 분명 사람은 실수를 하게 되어있다. 그러니 포인터를 사용할때는 초기화, 자원해제를 세심하게 다루자. 잊지말자 - 자원 누출을 막기 위해, 생성자 안에서 자원을 획득(초기화)하고 소멸자에서 그것을 해제하는 RALL객체를 사용하자! -일반적으로 널리 쓰이는 RALL 클래스는 tr1::shared_ptr 그리고 auto_ptr입니다. 이 둘 가운데 tr1::shared_ptr이 복사 시 동작이 더 직관적이니 대개 더 좋다. auto_ptr은 복사 시 원본 객체를 null로 만들고 복사된 객체에만 데이터가 존재한다. * RALL(Resource Acquisition Is Initialization) 원칙 - 안전하게 자원을 사용하기 위한, C++에서 자주 쓰는 패턴 의문점 스마트 포인터는 delete가 소멸자가 실행 될 때 실행되는건가?
CPP
・
C++
・
EffetiveC++
2022. 05. 31.
2
항목12 - 객체의 모든 부분을 빠짐없이 복사하자
객체 복사 시 모든 데이터 멤버가 빠지지 않도록 하자. 객체 복사 시 모든 기본 클래스 부분이 빠지지 않도록 하자. 복사 생성자와 대입 연산자 구현할때 주의점 - 한쪽을 이용해 다른 한쪽을 구현하려고 하지 말자 - 필요 시 공통된 동장을 제 3의 함수에 분리하자 - 양쪽에서 이 함수를 호출하도록 구현하자 객체 복사 함수 생성 시 주의해야할 것 - 사용자가 일부 데이터 복사를 누락해도 컴파일러는 알려주지 않는다! -> 누락된 멤버 변수가 없도록 해라(누락되면 부분복사된다) -> 상속 받은 클래스의 복사도 누락 없도록해라!! 잊지말자 1. 객체 복사 함수는 객체의 모든 것을 복사 누락없이! 2. 복사 함수 두개를 구현할 때 한쪽을 이용해서 다른 쪽을 구현하려는 시도 금지! 공통된 함수 만들어서 그 함수에서 필요한 함수를 호출할 것!
CPP
・
C++
・
EffectiveC++
2022. 05. 30.
0
UE4 콜리전(Collision)
콜리전(Collision)은 언리얼 엔진에서 물리적인 충돌이나 레이 캐스팅 실시간 처리를 해준다. 이러한 물리 시뮬레이션은 Collision Response(콜리전 반응) 및 Trace Response(트레이스 반응) 설정을 통해서 다른 오브젝트 유형과 어떻게 상호작용할지 정의된다. 종류 - 블록(Ignore) 충돌하는 두 오브젝트가 모두 블록이어야 두 오브젝트가 충돌했을 때, 겹치지 않고 서로에게 막히게 된다. 총알에 맞아서 깨지는 유리창 등을 구현 - 겹침(Overlap) 다른 오브젝트를 통과시키지만, 만약 Generate Overlap Event가 활성화된 상태라면 Overlap Event를 발생시킨다. 이 겹침 이벤트가 발생하려면 두 오브젝트 모두 겹침 이상으로 설정되어 있어야 한다. 만약 한 쪽은 겹침이고 다른 한 쪽이 무시인 상태라면 겹침 이벤트는 발생하지 않는다. - 무시(Ignore) 무시는 모든 오브젝트와 트레이스를 통과시키며 어떠한 이벤트도 발생시키지 않는다.
CPP
・
C++
・
UE4
2022. 05. 29.
0
항목11 - operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자!
operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자! 자기대입이란(self assignment)? 어떤 객체가 자기 자신에 대해 대입연산자를 적용하는 것을 말함 w = w; a[i] = a[j]; *px = *py; 같은 값을 같거나 같은 값을 가르키면 그것은 자기대입이 성립됨. 자기대입이 생기는 이유는 여러 곳에서 하나의 객체를 참조하는 상태인 '중복참조(aliasing)' 라고 불리는 것 때문! 자기대입이 안좋은 이유 - 코드가 커짐 - 처리 흐름에 분기점을 만들어 실행속도 느려짐 - CPU 명령어 선행인출, 캐시, 파이프러닝 등의 효과 떨어짐 해결책 - ' 옮긴 후 삭제! ' 1. 원래의 포인터변수 pb를 어딘가에 저장한다. Bitmap *pOrig = pb; 2. pb 가 *pb의 사본을 가리키게 한다. pb = new Bitmap(*rhs.pb); 3. 원래의 pb를 삭제한다. delete pOrig; - > new Bitmap 부분에서 예외가 발생하더라도 pb는 변경되지 않은 상태가 유지되어 예외에서 안전하다. - '복사 후 맞바꾸기(copy and swap)' 1. temp = 사본의 copy를 하나 만들고 그것을 원본과 스왑하는 기법 -> 클래스의 복사 대입 연산자는 인자를 값으로 취하도록선언하는 것이 가능하다는 점 -> 값에 의한 전달을 수행하면 전달된 대상의 사본이 생긴다는 점 잊지말자! - operator= 을 구현할 때, 어떤 객체가 그 자신에 대입되는 경우를 제대로 처리하도록 만듭시다. 원본 객체와 복사대상 객체의 주소를 비교해도 되고, 문장의 순서를 적절히 조정할 수도 있으며, 복사 후 맞바꾸기 기법을 써도 된다! - 두 개 이상의 객체에 대해 동작하는 함수가 있다면, 이 함수에 넘겨지는 객체들이 사실 같은 객체인 경우에 정확하게 동작하는지 확인해 보자!
CPP
・
C++
・
EffectiveC++
2022. 05. 29.
0
항목10 - 대입 연산자는 *this의 참조자를 반환하게 하자
C++ 대입연산자는 x=y=z=15; 가 허용된다. 좌변 객체의 참조자를 반환하게 만들자. 대입연산은 *this의 참조자를 반환하도록 만들어라.
CPP
・
C++
・
EffectiveC++
2022. 05. 28.
0
LV1 - 최소직사각형 만들기
의 min, max 함수에 대한 이해랑 숙련도가 부족했다. min, max를 생각을 미처 못했다. - min(a, b) : a와 b를 비교하여 가장 작은 값을 반환한다. - max(a, b) : a 와 b를 비교하여 가장 큰 값을 반환한다. 내 풀이 int solution(vector> sizes) { int answer = 0; vector W; vector H; vector temp; int maxSize; bool moreBig = false; // 가로 세로 vector로 분리. for (int i = 0; i { W.push_back(sizes[i][0]); H.push_back(sizes[i][1]); } // 가로 세로 오름차순으로 정렬. sort(W.begin(), W.end()); sort(H.begin(), H.end()); // 가로 세로에서 가장 큰 수 찾고 가로에 큰 수 있으면 moreBig true 세로에 큰 수가 있으면 false. maxSize = W.back() > H.back() ? W.back() : H.back(); moreBig = W.back() > H.back() ? true : false; if (moreBig == true) { for (int i = 0; i { if (sizes[i][0] sizes[i][1] = sizes[i][0]; temp.push_back(sizes[i][1]); } sort(temp.begin(), temp.end()); answer = maxSize * temp.back(); } else { for (int i = 0; i { if (sizes[i][0] > sizes[i][1]) sizes[i][0] = sizes[i][1]; temp.push_back(sizes[i][0]); } sort(temp.begin(), temp.end()); answer = maxSize * temp.back(); } return answer;} 잘한 사람 풀이 int solution(vector> sizes) { int answer = 0; int w = 0, h = 0; for (int i = 0; i { w = max(w, min(sizes[i][0], sizes[i][1])); h = max(h, max(sizes[i][0], sizes[i][1])); } answer = w * h; return answer;}
CPP
・
C++
・
알고리즘
2022. 05. 27.
0
항목9 - 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자
항목 9: 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자 이유 객체의 생성과 소멸과정 중 가상 함수가 소멸된 상태면 링킹 에러가 발생한다. 파생 클래스의 데이터가 아직 초기화된 상태가 아니기 때문에, C++은 아예 없었던 것처럼 취급하고 파생클래스의 가상 함수는 기본클래스의 가상함수를 기반으로 이뤄진다. 요약 기본 클래스 생성자 호출 시점에 객체 타입은 기본 클래스 - 호출 되는 가상 함수는 모두 기본 클래스 타입으로 결정됨 - 런타임 타입 정보 사용 요소(dynamic_cast, typeid 등) 사용 시에도 기본 클래스 타입으로 취급 주의 - 만약 여러 생성자로 인해 공통 작업을 별도의 함수로 정의할 경우 컴파일러 오류가 없어 찾기 어렵다 기억하자! - 생성 소멸 과정 중에는 가상 함수를 호출하자! - 하려거든 가상 함수를 비가상 함수로 바꿀 것!
CPP
・
C++
・
EffecitveC++
2022. 05. 25.
0
항목8 - 예외가 소멸자를 떠나지 않도록 붙들어 놓자
예외가 소멸자를 떠나지 못하도록 붙들어 놓자. 소멸자가 호출 되는 경우 1. 정상적으로 객체가 종료되었을 때 2. 예외처리 메커니즘에 의해 객체가 소멸될 때 소멸자가 예외가 있으면 안되는 이유 예를 들어 10의 크기를 갖는 벡터 v가 있다. 함수를 사용한 다음에서야 10개 만큼 메모리가 해제된다. 만약 v의 첫번째 주소에서 문제가 생겨 예외가 발생했다면??? -> 나머지 2~10의 메모리가 누수되는 것이다. 다른 예를 들어 class DBConn { public: ~DBConn() { db.close(); } private: DBConnection db; }; 위 코드에서 프로그램이 종료되기 위해 ~DBConn() 호출하였는데, 여기서 예외 발생 시, 프로그램이 미정의 동작을 발생시킬 것이다. 그냥 예외가 남은채로 끝나는 것이다. 소멸자에서 예외가 나면 해결방법! 1. close에서 예외가 발생하면 프로그램을 바로 끝내라. -> 에러 발생 후에 프로그램 지속이 어려운 경우 괜찮은 선택이다. 2. close를 호출한 곳에서 일어난 예외를 무시하라. -> 예외를 무시한 뒤라도 프로그램이 신뢰성 있게 실행 될 수 있는 상태일 경우. 3. close 호출 책임을 소멸자에서 사용자로 넘겨라! 정리 1. 일반적으로 C++은 예외를 내보내는 소멸자를 좋아하지 않는다. 2. 예외는 소멸자가 아닌 다른 함수에서 비롯된 것이어야 한다! -> 소멸자에 있다면 사용자는 예외에 대처할 기회가 없다. 임시방편으로 무시할뿐. 3. 소멸자에서 예외가 발생하지 않도록 하자! -> 예외는 소멸자가 아닌 함수에서 처리하도록 하자! 4. 소멸자에서 호출되는 함수가 예외 가능성이 있다면 -> 소멸자에서 삼켜버리던지, 프로그램을 종료하던지 처리하자. 5. 소멸자에서 예외가 생길 경우 자체를 배제해서 코드를 작성하는 것이 최선이다.
CPP
・
C++
・
EffectiveC++
2022. 05. 25.
0
LV1 - 문자열내마음대로정렬하기
1. sort 함수 이용하여 strings 정렬하되 사용자정의 함수인 'cmp()' 사용 2. 비교 함수 cmp를 만들어 조건에 맞게 되있으면 true, 아니면 false - Code #include #include #include using namespace std; int N; vector solution(vector strings, int n); bool cmp(string a, string b); int main() { vector s = { "abce", "abcd", "cdx" }; solution(s,2); return 0; } vector solution(vector strings, int n) { N = n; sort(strings.begin(), strings.end(), cmp); return strings; } bool cmp(string a, string b) { if (a[N] == b[N]) { return a } else { return a[N] } }
C++
・
CPP
2022. 05. 23.
0
LV1 - 같은 숫자는 싫어
배열에서 반복되는 수를 제거하여 나열하라. algorithm 라이브러리에서 'unique'라는 키워드를 이용해 배열을 중복된 수가 없이 나열시킨다. 그 후 erase라는 vector 명령어를 통해 나열되고 필요없는 데이터들은 지운다. 굉장히 깔끔하고 멋진 코드인 것 같다. #include #include #include using namespace std; vector solution(vector arr); int main() { vector arr = { 1,1,3,3,0,1,1 }; solution(arr); return 0; } vector solution(vector arr) { arr.erase(unique(arr.begin(), arr.end()), arr.end()); vector answer = arr; return answer; }
CPP
・
C++
・
알고리즘