일지
-
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을 붙이지만 그렇다고 구현하는 함수 템플릿에 필요도 ..
-
Effective C++...27일지 2022. 7. 19. 08:18
예외 안전성이 확보되는 그날 위해 싸우고 또 싸우자! 예외 안전성을 가진 함수의 동작 예외 안전성을 가진 함수는 다음과 같이 동작해야 한다. 자원이 새지 않도록 만든다. 자료구조가 더럽혀지는 것을 허용하지 않는다. 다음의 예제의 new Image(imgSrc)에서 에러가 발생하면 이 동작이 모두 정상적으로 작동하지 않는다. class PrettyMenu { public: ... void changeBackground(std::istream& imgSrc); // 이미지 변경 함수 ... private: Mutext mutext; Image* bgImage; // 현재 배경 int imageChanges; // 이미지 변경 횟수 } void PrettyMutext::changeBackground(std::..
-
Effective C++...26일지 2022. 7. 18. 08:59
내부에서 사용하는 객체에 대한 '핸들'을 반환하는 코드는 되도록 피하자 함수의 반환형에 의해 캡슐화 변동 기본적으로 멤버 변수를 private으로 선언했다고 하더라도 public함수가 해당 멤버 변수를 참조형 또는 포인터로 반환한다면 이 멤버 변수는 public으로 봐야 한다. 즉, 객체의 내부 요소는 함수의 핸들 반환 시에도 캡슐화의 정도가 달라지게 된다. 다음과 같이 사각형을 나타내는 클래스가 있을 때 사용자가 사각형의 정보를 볼 수 있게 하기 위해 참조형을 반환한다면 반환된 값을 통해 수정될 수 있는 위험이 있다. struct RectData { Point ulhc; Point lrhc; }; class Rectangle { ... private: std::tr1::shared_ptr pData; ..