일지
-
Effective C++...35일지 2022. 8. 6. 10:10
어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자 가상 함수와 기본 매개변수의 바인딩 차이 가상 함수의 경우 동적으로 바인딩되는 반면 기본 매개변수는 정적으로 바인딩된다. 즉, 파생 클래스의 가상 함수에서 기본 매개변수를 바꿨더라도 기본 클래스의 기본 매개변수 값을 사용하게 될 수도 있다. 이런 식의 도작이 발생하는 이유는 컴파일러의 메커니즘이 속도 유지와 구현 간편성에 무게를 두고 있기 때문이다. ※ 비가상 인터페이스 관용구를 사용해 기본 매개변수를 고정할 수 있다. 더보기 참고문헌 스콧 마이어스.(2015.03.26).이펙티브 C++
-
Effective C++...34일지 2022. 8. 5. 07:27
상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물! 문제가 되는 이유 다음과 같이 상속된 클래스의 비가상 함수를 재정의하는 경우 derived 클래스의 해당 함수는 부모의 함수를 호출할 수도, derived 클래스의 함수를 호출할 수도 있는 상태가 된다. class B { public: void mf(); }; class D : public B { public: // 상속된 비가상 함수 mf를 재정의 void mf(); }; B x; B* pB = &x; pB->mf(); // B의 mf 실행 D* pD = &x; pD->mf(); // B의 mf가 실행될 수도 있고 D의 mf가 실행될 수도 있다. 이러한 문제가 발생하는 원인은 비가상 함수가 정적 바인딩으로 묶이기 때문에 클래스가 생성될..
-
Effective C++...33일지 2022. 8. 4. 21:25
가상 함수 대신 쓸 것들도 생각해 두는 주세를 시시때때로 길러 두자 가상 함수를 대체할 수 있는 방법들 어떤 공통적인 연산을 수행하는 함수를 구현할 때 가상 함수 대신 다음과 같은 구현도 가능하다. 비가상 함수 인터페이스 관용구 비가상 함수로 가상 함수를 감싸서 가상 함수를 감추는 방법 함수 포인터 전략 패턴 함수 포인터를 이용해 외부 함수를 사용하는 방법 tr1::function 전략 패턴 STL 라이브러리를 이용해 일반적인 형태의 함수를 사용하는 방법 고전적인 전략 패턴 공통 연산을 수행하는 함수를 가진 클래스 계열을 생성해 사용하는 방법 비가상 함수 인터페이스 관용구 예제와 특징 비가상 함수를 호출할 수 있도록 하고 private 가상 함수를 만들어 상속된 클래스에 따라 구현을 달리할 수 있다. c..
-
Effective C++...32일지 2022. 8. 3. 08:37
인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 함수의 종류 C++에는 다음과 같이 함수를 구분해 사용할 수 있다. 순수 가상 함수 함수를 선언만 하고 구현을 하지 않음으로 파생 클래스에 구현 의무를 넘겨주는 인터페이스 역할을 한다. 단순 가상 함수 함수의 기본적인 구현을 하여 파생 클래스에서 필요한 경우에만 함수의 구현을 수정할 수 있도록 한다. 비 가상 함수 파생 클래스에서 구현을 변경할 여지를 주지 않는 일반적인 구현 방식이다. 단순 가상 함수의 문제점 단순 가상 함수는 기본적인 구현이 존재하기 때문에 파생 클래스를 구현할 때 구현이 필요하다는 것을 잊을 수 있다. 따라서 순수 가상 함수를 함께 활용하여 구현 의무를 전달할 수 있다. class Airplane { public: // ..
-
Effective C++...31일지 2022. 8. 2. 08:40
상속된 이름을 숨기는 일은 피하자 C++의 유효 범위 탐색 과정과 문제 만약 프로그램 실행 중 특정 함수가 발견됐다면 해당 함수를 찾기 위해 컴파일러는 다음의 과정을 밟게 된다. 지역의 유효 범위 탐색 Derived 클래스의 유효 범위 탐색 Base 클래스의 유효 범위 탐색 네임 스페이가 있으면 네임 스페이스 내부 범위 탐색 전역 유효범위 탐색 이 과정에서 Base 클래스에 존재하는 함수와 동일한 이름의 함수를 Derived 클래스에서 생성했다면 함수의 매개 변수가 다르거나 비가상 함수라고 하더라도 Base 클래스의 함수의 이름이 가려지게 된다. class Base {private: int x;public: virtual void mf1() = 0; virtual void mf1(int); virtual..
-
Effective C++...30일지 2022. 7. 29. 08:39
public 상속 모형은 반드시 "is-a(...는 ...의 일종이다)"를 따르도록 만들자 public 상속의 is-a 관계 모든 사람은 학생이 아니지만 학생은 사람이다. 이 것의 관계가 public 상속이라고 할 수 있다. 이를 코드로 만들면 다음과 같다. class Person { ... void eat() { ... } }; class Student : public Person { ... void study() { ... } }; 사람의 일종인 학생은 사람이 할 수 있는 모든 것을 하지만 모든 사람이 공부하지는 않는다. 그런데 이러한 설계가 잘못되면 문제가 생길 수 있다. 모든 새는 난다고 가정해서 Bird 클래스에 fly 함수를 만들었다면 날지 못하는 새인 펭귄은 Bird를 상속받았을 때 fly ..
-
Effective C++...29일지 2022. 7. 26. 21:09
파일 사이의 컴파일 의존성을 최대로 줄이자 컴파일 의존성이란 하나의 클래스가 수정되었을 때 그 클래스를 사용하는 클래스가 함께 컴파일되어야 하는 경우 컴파일 의존성이 있다고 한다. 다음 Person 클래스에서 사용된 변수의 클래스가 수정된다면 Person 뿐만 아니라 Person을 사용하는 모든 클래스도 함께 다시 컴파일되어야 한다. class Person { public: Person(const std::string& name, const Date& birthday, const Address& addr); std::string name() const; std::string birthDate() const; std::string address() const; ... private: std::string ..
-
Effective C++...28일지 2022. 7. 25. 16:46
인라인 함수는 미주알고주알 따져서 이해해 두자 인라인 함수의 장, 단점 인라인 함수는 함수 호출 문을 본문으로 바꿔치기하는 것이기 때문에 속도 면에서 이득을 볼 수 있다. 다만 긴 함수를 인라인으로 사용해 여기저기에서 복사된다면 목적 코드의 크기가 커지는 문제가 생긴다. 반대로 간단한 처리를 하는 함수 명을 길게 설명식으로 사용하고 인라인 함수로 바꾼다면 오히려 목적 코드의 크기가 작아질 수도 있다. ※ 인라인 문은 컴파일러에 요청하는 것이기에 컴파일러에 따라 인라인화 될 수도 안 될 수도 있다. 인라인 함수의 위치 인라인 함수와 템플릿은 기본적으로 헤더에 들어 있어야 한다. 템플릿 인스턴스화는 인라인과 별개이며 템플릿을 인라인화 하는 경우 inline을 붙이지만 그렇다고 구현하는 함수 템플릿에 필요도 ..