분류 전체보기
-
Effective C++...17일지 2022. 6. 18. 14:49
인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자 새로운 타입을 만들어 실수 막기 인터페이스에서 요구하는 특정한 타입이 존재하는 경우 사용자가 실수하더라도 쉽게 그 실수를 인지할 수 있게 된다. class Date { public: Date(int month, int day, int year); // 단순히 int를 사용하는 경우 }; Date(13, 2, 2022); // 입력 순서를 틀리거나 Date(2, 40, 2022); // 존재하지 않는 값을 넘기게 될 수 있다. 위와 같은 경우를 다음과 같이 년, 월, 일을 나타내는 타입을 도입하면 막을 수 있게 된다. struct Day; struct Month; struct Year; class Date { public: Date(con..
-
[Effective C++] 자원관리프로그래밍 기초/C++ 2022. 6. 17. 07:30
자원관리 자원 관리에는 객체가 그만! 자원을 안전하게 사용할 수 있는 조건 자원 관리를 수동으로 하게 되면 예상하지 못한 시점에 함수가 반환되거나 예외가 발생하는 경우 처리가 어려워지게 된다. 이 것을 막기 위해 자원을 특정 객체에 넘기고 객체가 소멸될 때 자원을 삭제하도록 하면 안전하게 처리가 가능하다. 이 자원 관리 객체는 다음의 조건을 만족해야 한다. 자원을 획득한 후에 자원 관리 객체에게 넘긴다. 자원 관리 객체는 자신의 소멸자를 사용해서 자원이 확실하게 해제되도록 한다. 자원 관리 객체의 예와 주의 사항 대표적인 자원 관리 객체에는 스마트 포인터가 있다. 그런데 스마트 포인터는 객체의 제거 시 delete를 사용하기 때문에 배열을 동적 생성했을 때 안전하게 삭제해 줄 수 없다. 이러한 이유는 대..
-
Effective C++...16일지 2022. 6. 16. 07:26
new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 C++의 연산 실행 순서 다른 언어와 달리 C++는 연산 실행 순서가 컴파일러 제조사마다 다르다. 그렇기 때문에 스마트 포인터에 자원이 저장되기 전에 에러가 발생하는 경우가 있을 수 있다. 다음은 문제가 될 수 있는 코드이다. processWidget(std::tr1::shared_ptr(new Widget), priority()); 위 코드의 실행 순서는 new Widget은 항상 먼저 실행되지만 shared_ptr의 생성자와 priority()의 실행 순서는 바뀔 수 있다. 그런데 priority() 가 먼저 실행되는 경우에 priority()에서 에러가 발생한다면 스마트 포인터에 자원이 들어가기 전에 에러가 발생했으므..
-
Effective C++...15일지 2022. 6. 15. 07:25
new 및 delete를 사용할 때는 형태를 반드시 맞추자 delete의 동작 방식 기본적인 delete는 주어진 객체의 소멸자를 호출하고 메모리에서 제거한다. 반면에 delete[]는 컴파일러에게 주어진 객체가 배열이라는 사실을 전달하게 되고 컴파일러는 해당 포인터 앞의 몇 바이트를 읽어 배열의 크기를 확인하고 그 크기만큼 객체의 소멸자를 호출하고 메모리에서 제거한다. 형태를 맞추지 않을 때 문제가 되는 경우 배열이 아닌 객체를 delete[]로 제거하는 경우 객체 앞의 몇 바이트를 읽고 그만큼 제거하려고 시도하지만 해당 위치에 소멸자가 없거나 다른 객체가 있을 것이므로 에러가 발생한다. 배열을 delete로 제거하는 경우 주어진 배열의 첫 번째 객체만 제거하고 나머지 요소들은 메모리에 그대로 남게 된..
-
Effective C++...14일지 2022. 6. 14. 07:42
자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자 외부 접근이 필요한 이유와 방법 API를 사용하거나 하위 클래스의 함수가 필요한 경우 형 변환이 필요할 수 있다. 이때, 자원 관리 클래스 자체를 사용할 수 없으므로 자원에 접근할 방법이 필요하다. 자원의 외부 접근 방식은 다음 두 가지로 나뉜다. 암시적 변환 대입 연산을 통해 변환이 되도록 만드는 방법 명시적 변환 직접적으로 함수 호출을 통해 자원을 접근하는 방법 두 방법에 장단점이 있는데 암시적 변환은 코드 사용성이 증가하지만 위험성도 증가한다는 문제가 있고 명시적 변환은 그와 반대로 위험성은 낮지만 코드 사용성이 떨어지게 된다. 따라서 전체 프로그램의 방향성에 따라 적절한 방법을 선택하면 된다. ※ 자원 관리 클래스는 데이터 은닉..
-
Effective C++...13일지 2022. 6. 13. 07:50
자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자 스마트 포인터가 적합하지 않은 경우 힙에서 관리되는 자원이 아닌 경우에는 스마트 포인터로 처리하는 게 알맞지 않다. 이 경우 스스로 자원 관리 클래스를 만들어야 할 수 있다. 그 예로 뮤텍스를 관리하는 클래스가 있는 경우 다음과 같이 만들 수 있다. class Lock { public: explicit Lock(Mutex* pm) : mutexPtr(pm) { lock(mutexPtr); } // 생성자에서 락을 걸고 ~Lock() { unlock(mutexPtr); } // 소멸자에서 락을 해제한다. private: Mutex* mutexPtr; }; 자원 관리 클래스의 복사 처리 방법 자원 관리 클래스에서 복사가 필요한 경우 자신의 의도에 따라 ..
-
Effective C++...12일지 2022. 6. 12. 15:39
자원 관리에는 객체가 그만! 자원을 안전하게 사용할 수 있는 조건 자원 관리를 수동으로 하게 되면 예상하지 못한 시점에 함수가 반환되거나 예외가 발생하는 경우 처리가 어려워지게 된다. 이 것을 막기 위해 자원을 특정 객체에 넘기고 객체가 소멸될 때 자원을 삭제하도록 하면 안전하게 처리가 가능하다. 이 자원 관리 객체는 다음의 조건을 만족해야 한다. 자원을 획득한 후에 자원 관리 객체에게 넘긴다. 자원 관리 객체는 자신의 소멸자를 사용해서 자원이 확실하게 해제되도록 한다. 자원 관리 객체의 예와 주의 사항 대표적인 자원 관리 객체에는 스마트 포인터가 있다. 그런데 스마트 포인터는 객체의 제거 시 delete를 사용하기 때문에 배열을 동적 생성했을 때 안전하게 삭제해 줄 수 없다. 이러한 이유는 대부분의 배..
-
[Effective C++] 생성자, 소멸자 및 대입 연산자프로그래밍 기초/C++ 2022. 6. 11. 14:46
생성자, 소멸자 및 대입 연산자 C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 기본적으로 생성되는 멤버 함수 개발자가 따로 생성하지 않으면 컴파일러에서 기본적인 모양으로 만드는 멤버 함수들이 존재한다. 생성자 인자가 없는 기본 생성자를 생성한다. 소멸자 아무 기능 없는 소멸자를 생성한다. 복사 생성자 복사가 가능한 경우 복사 생성자를 생성한다. 멤버가 참조형이거나 상수인 경우 복사가 불가능하다. 복사 대입 연산자 기본 클래스에서 복사 대입 연산자를 private으로 하지 않은 경우 복사 대입 연산자를 생성한다. ※ 복사 생성자와 복사 대입 연산자의 경우 생성이 불가능할 경우 컴파일 에러가 발생한다. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자 private으로..