언어/C++

언어/C++

[Effective C++] 멤버 함수보다는 비멤버 비프렌드 함수와 더 까가워지자

항목 23 : 멤버 함수보다는 비멤버 비프렌드 함수와 더 까가워지자 웹브라우저를 나타내는 클래스가 하나 있다고 가정합시다. 웹브라우저 클래스라면 여러 기능을 제공하는 함수가 많을 것입니다. 캐시를 비우는 함수, URL의 기록을 없애는 함수, 쿠키를 전부 제거하는 함수등이 있겠죠. 1 2 3 4 5 6 7 8 class WebBrowser { public: ... void clearCache(); void clearHistory(); void removeCookies(); ... }; 하지만 사용자 중에는 이 세 동작을 한 번에 하고 싶은 분들도 있기 때문에, 세 함수를 모아서 불러주는 함수도 준비해 둘 수 있을 것입니다. 1 2 3 4 5 6 class WebBrowser { public: ... voi..

언어/C++

[Effective C++] 데이터 멤버가 선언될 곳은 private 영역임을 명심하자

항목 22 : 데이터 멤버가 선언될 곳은 private 영역임을 명심하자 이번 항목에서는 데이터 멤버가 어째서 public이면 안 되는지에 대한 이유를 알아보고, public 데이터 멤버에 대한 모든 이야기가 protected 데이터 멤버에도 똑같이 적용되는 모습을 함께 확인하도록 하지요. public 데이터 멤버는 왜 안 될까요? 우선 문법적 일관성이 이유가 되겠습니다. 데이터 멤버가 public이 아니라면, 사용자 쪽에서 어떤 객체를 접근할 수 있는 유일한 수단은 멤버 함수일 것입니다. 그렇다면 그 클래스의 멤버에 접근하고 싶을 때 그냥 함수를 쓰기만 하면 됩니다. 만일, 어떤 데이터 멤버를 public으로 내놨다면 모두가 이 멤버에 대해 읽기 및 쓰기 접근권한을 가지게 되지만, 이 값을 읽고 쓰는 ..

언어/C++

[Effective C++] 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자

항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자 유리수를 나타내는 클래스가 하나 있다고 가정합시다. 이 클래스에는 두 유리수를 곱하는 멤버 함수가 선언되어 있습니다. 1 2 3 4 5 6 7 8 9 10 11 12 class Rational { public : Rational(int numerator = 0, int denominator = 1); ... private : int n, d; friend const Rational operator*(const Rational& lhs, const Rational& rhs); }; Colored by Color Scripter 여기서 operator*를 보면 이 함수가 참조자를 반환하도록 만들어졌다면, 이 함수가 반환하는 참조..

언어/C++

[Effective C++] '값에 의한 전달'보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다

항목 20 : '값에 의한 전달'보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다 기본적으로 C++는 함수로부터 객체를 전달받거나 함수에 객체를 전달할 때 '값에 의한 전달' 방식을 사용합니다. 특별히 다른 방식을 지정하지 않는 한, 함수 매개변수는 실제 인자의 '사본'을 통해 초기화되며, 어떤 함수를 호출한 쪽은 그 함수가 반환한 값의 '사본'을 돌려받습니다. 이들 사본을 만들어내는게 복사 생성자 입니다. 이 점 때문에 '값에 의한 전달'이 고비용의 연산이 되기도 합니다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Person { public : Person(); virtual ~Person(); ... private ..

언어/C++

[Effective C++] 클래스 설계는 타입 설계와 똑같이 취급하자

항목 19 : 클래스 설계는 타입 설계와 똑같이 취급하자 여러분은 효과적인 클래스를 설계할 때 어떻게 하십니까? 여러분이 직면하게 될 고려사항이 무엇인지부터 파악하는 것이 우선이겠지요. 어떤 클래스를 설계하든 간에 사실상 모든 경우에 여러분의 후두부를 괴롭힐 질문들을 아래에 모아 보았습니다. 이들 질문의 대답에 따라 설계를 제한하는 것들이 생기게 되는데, 이 부분 역시 신경 쓰지 않으면 안됩니다. 새로 정의한 타입의 객체 생성 및 소멸은 어떻게 이루어져야 하는가? 이 부분이 어떻게 되느냐에 따라 클래스 생성자 및 소멸자의 설계가 바뀝니다. 그뿐 아니라 메모리 할당 함수(operator new, operator new[], operator delete, operator delete[] 입니다. 8장 참조)..

언어/C++

[Effective C++] 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자

항목 18 : 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자 '제대로 쓰기에 쉽고 엉터리로 쓰기에 어려운' 인터페이스를 개발하려면 우선 사용자가 저지를 만한 실수의 종류를 머리에 넣어두고 있어야 합니다. 새로운 타입을 들여와 인터페이스를 강화하면 상당수의 사용자 실수를 막을 수 있습니다. 일단 적절한 타입만 제대로 준비되어 있으면, 각 타입의 값에 제약을 가하더라도 괜찮은 경우가 생기게 됩니다. 예를 들면 월이 가질 수 있는 유효한 값은 12개이므로, Month라는 타입은 이 사실을 제약으로 사용 할 수 있습니다. 예상되는 사용자 실수를 막는 다른 방법으로는 어떤 타입이 제약을 부여하여 그 타입을 통해 할 수 있는 일들을 묶어 버리는 방법이 있습니다. 제약 부여 방법으로 아주 흔히 ..

언어/C++

[Effective C++] new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자

항목 17 : new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 처리 우선순위를 알려 주는 함수가 하나 있고, 동적으로 할당한 Widget 객체에 대해 어떤 우선순위에 따라 처리를 적용하는 함수가 하나 있다고 가정합시다. 1 2 int prioirty(); void processWidget(std::tr1::shared_ptr pw, int prioirty); 자원 관리에는 객체를 사용하는 것이 좋기 때문에 processWidget 함수는 동적 할당된 Widget 객체에 대해 스마트 포인터를 사용하도록 만들어졌습니다. 이렇게 만들어진 processWidget 함수를 이제 호출합니다. 1 processWidget(new Widget, prioirty()); 이렇게 호출을 하..

언어/C++

[Effective C++] new 및 delete를 사용할 때는 형태를 반드시 맞추자

항목 16 : new 및 delete를 사용할 때는 형태를 반드시 맞추자 아래에 적어 놓은 것에서 뭔가 잘못된 점이 보이나요? 1 2 3 std::string *stringArray = new std::string[100]; ... delete stringArray; 아무런 문제가 없어 보이지만, 100개의 string 객체 가운데 99개는 정상적인 소멸과정을 거치지 못할 가능성이 큽니다. 여러분이 new 연산자를 사용해서 표현식을 꾸미게 되면, 이로 인해 두 가지의 내부 동작이 진행됩니다. 일단 메모리가 할당됩니다. 그 다음, 할당된 메모리에 대해 한 개 이상의 생성자가 호출됩니다. delete 표현식을 쓸 경우에는 또 다른 두 가지의 내부 동작이 진행되는데, 우선 기존에 할당된 메모리에 대해 한 개 ..

언어/C++

[Effective C++] 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자

항목 15 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자 자원 관리 클래스는 재치 만발의 듬직한 클래스입니다. 실수로 터질 수 있는 자원 누출을 튼튼히 막아 주는 보호벽 역할을 해 주니까요. 1 std::tr1::shared_ptr pInv(createInvestment()); 이때 어떤 Investment 객체를 사용하는 함수로서 여러분이 사용하려고 하는 것이 다음과 같다고 가정해 봅시다. 1 int daysHeld(const Investment *pi); // 투자금이 유입된 이후로 경과한 날수 그리고 이렇게 호출하고 싶을 텐데요. 1 int days = daysHeld(pInv); // 에러 애석하게도 이 코드는 컴파일이 안 됩니다. daysHeld 함수는 Investme..

언어/C++

[Effective C++] 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자

항목 14 : 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자 자원 관리 클래스를 스스로 만들어야 할 필요를 느끼는 경우가 있습니다. 예를 하나 들어 보죠, Mutex 타입의 뮤텍스 객체를 조작하는 C API를 사용하는 중이라고 가정합시다. 이 C API에서 제공하는 함수 중엔 lock 및 unlock이 있고요. 1 2 3 void lock(Mutex *pm); // pm이 가리키는 뮤텍스에 잠금을 겁니다. void unlock(Mutex *pm) // pm이 가리키는 해당 뮤텍스의 잠금을 풉니다. 그런데 뮤텍스 잠금을 관리하는 클래스를 하나 만들고 싶습니다. 이전에 걸어 놓은 뮤텍스 잠금을 잊지 않고 풀어 줄 목적인 거죠. 이런 용도의 클래스는 기본적으로 RAII 법칙을 따라 구성합니다. 즉, ..

지나가던 개발자
'언어/C++' 카테고리의 글 목록 (3 Page)