전체 글

값에 의한 전달보다는 상수 객체 참조자에 의한 전달을 사용해라. 대체적으로 효율적이고 복사손실을 막을 수 있다. 기본제공 타입 및 STL반복자, 함수 객체 타입에는 값에 의한 전달이 더 적절하다. 값에 의한 전달보다는 상수객체 참조자에 의한 전달 C++은 함수로부터 객체를 전달받거나 함수에 객체를 전달할 때 값에 의한 전달 방식을 사용한다. 특별히 다른 방식을 지정하지 않는 한, 함수 매개변수는 실제 인자의 사본을 통해 초기화되며, 어떤 함수를 호출한 쪽은 그 함수가 반환한 값의 사본을 돌려받는다. 하지만, 값에 의한 전달은 비용이 비싸다. class Person { public: Person(); virtual ~Person(); ... private: std::string name; std::stri..
클래스 설계는 타입 설계와 같다. 새로운 타입을 정의하기 전에 몇 가지 고려사항을 점검해 보자. 클래스 설계는 타입 설계 여느 객체 지향 프로그래밍 언어처럼, C++에서 새로운 클래스를 정의한다는 것은 새로운 타입을 정의하는 것과 같다. C++ 개발을 한다는 것은 타입을 새로 만드는 일과 같으며 함수와 연산자를 오버로드하고, 메모리 할당 및 해제를 제어하며, 객체 초기화 및 종료처리를 정의하는 작업 모두 관리해 주어야 한다. 좋은 클래스를 설계하는 것은 꽤 어렵다. 문법이 자연스럽고, 의미구조가 직관적이며, 효율적인 구현이 가능해야 한다. 성능 또한 무시할 수 없는 부분이다. 다음은 좋은 클래스를 설계하기 위해 고려해 볼 사항 몇 가지이다. 새로 정의한 타입의 객체 생성 및 소멸은 어떻게 이루어져야 하는..
좋은 인터페이스는 제대로 쓰기엔 쉽고 틀리게 쓰기엔 어렵다. 인터페이스를 만들 때는 이 특성을 지닐 수 있도록 고민해야 한다. 사용자의 실수를 방지하는 방법으로는 새로운 타입 만들기, 타입에 대한 연산 제한, 객체의 값에 대해 제약 걸기, 자원 관리 작업을 사용자 책임으로 놓지 않기가 있다. 인터페이스의 올바른 사용을 이끄는 방법으로는 인터페이스 사이의 일관성 잡아주기, 기본 제공 타입과의 동작 호환성 유지하기가 있다. tr1::shared_ptr은 사용자 정의 삭제자를 지원한다. 이 특징 때문에 tr1::shared_ptr은 교차 DLL 문제를 막아 주며, 뮤텍스 등을 자동으로 잠금 해제하는 데 사용할 수 있다. 인터페이스는 제대로 쓰기엔 쉽게, 틀리게 쓰기엔 어렵게 C++에서 인터페이스의 활용도는 매..
new로 생성한 객체를 스마트 포인터에 넣는 코드는 한 문장으로 만들어라. 그렇지 않으면, 예외가 발생될 때 자원 누출 가능성이 생긴다. 새로 생성한 객체를 스마트 포인터로 관리할 때 주의점 자원 누출을 막기 위해 스마트 포인터를 사용하는 것은 좋은 방법이다. 하지만, 이 방법을 사용하더라도 자원 누출이 발생할 수 있다. int priority(); // 우선순위를 알려주는 함수 void processWidget(std::tr1::shread_ptr pw, int priority); // 우선순위에 따라 처리 우선순위에 따라 어떠한 작업을 하는 함수가 있다고 가정하자. processWidget(new Widget, priority()); 이렇게 함수를 사용할 수 없다. tr1::shared_ptr의 생성..
new 표현식에 []를 썼으면, 대응되는 delete 표현식에도 []를 써야 한다. 마찬가지로 new 표현식에 []를 안 썼으면, delete 표현식에도 []를 쓰면 안 된다. new, delete 사용 시 주의점 std::string *stringArray = new std::string[100]; ... delete stringArray; 문제가 없어 보이는 코드이지만, 미정의 동작을 보이게 된다. 최선의 경우에도 stringArray가 가리키는 100개의 string 객체 중 99개는 정상적으로 소멸되지 않을 가능성이 크다. 삭제되는 포인터가 객체 하나만 가리키는지 객체의 배열 가리키는지에 따라 delete가 소멸자를 몇 번 호출할지 결정한다. 단일 객체와 객체 배열에 대한 메모리 배치구조가 다르기..
실제 자원을 직접 접근해야 하는 기존 API들도 많기 때문에, RAII 클래스를 만들 때는 그 클래스가 관리하는 자원을 얻을 수 있는 방법을 제공해야 한다. 자원 접근은 명시적 변환 혹은 암시적 변환을 통해 가능하다. 안전성만 따지면 명시적 변환이 대체로 낫지만, 편의성을 보면 암시적 변환이 더 낫다. 자원 관리 클래스에서의 자원 접근 허용 자원 관리 클래스는 자원 누출을 막을 수 있는 보호막 역할을 한다. 하지만, 자원에 대한 직접적인 접근이 필요한 상황이 있다. 예를 들어, 스마트 포인터를 이용하여 자원 관리를 하는 경우 원래의 자원을 매개변수로 사용해야 하는 함수가 있을 때 스마트 포인터를 넘긴다면 에러가 발생한다. std::tr1::shared_ptr pInv(createInvestment());..
RAII 객체의 복사는 그 객체가 관리하는 자원의 복사 문제를 안고 가기 때문에, 그 자원을 어떻게 복사하느냐에 따라 RAII 객체의 복사 동작이 결정된다. RAII 클래스에 구현하는 일반적인 복사 동작은 복사를 금지하거나 참조 카운팅을 해주는 식으로 처리한다. 물론 다른 방법도 가능하다. 자원 관리 클래스의 복사 동작 힙에 생성되지 않는 자원은 스마트 포인터로 처리해 주기엔 일반적으로 맞지 않다. 예를 하나 들어보자. Mutex 타입의 뮤텍스 객체를 조작하는 C API를 사용 중이라고 가정해보자. void lock(Mutex *pm); // pm이 가리키는 뮤텍스에 잠금을 건다. void unlock(Mutex *pm) // pm이 가리키는 뮤텍스의 잠금을 푼다. 뮤텍스 잠금을 관리하는 클래스를 만드려..
hvv_an
이미난