C++ 스킬 15: 인터페이스 설계는 제대로 쓰기엔 쉽게 엉터리로 쓰기엔 어렵게 하자
C++ 스킬 16: 효과적인 클래스 설계를 위해 고려해야 할 부분들
1. 복사 생성자, 대입 생성자를 어떻게 둘 것인가.
2. 객체 생성과 소멸을 어떻게 할 것인가. (팩토리 함수, 직접 할당 해제)
3. 만든 클래스를 상속 시킨다고 하면 가상 함수를 어떻게 설정한 것인가.. (소멸자 등)
4. 암시적 명시적 타입변환을 허용할 것인가 (암시적: 타입 변환 연산자 operator T 생성) (명시적: 해당 변환을 하는 별도의 함수)
5. 예외 안정성, 자원 사용을 보장할 수 있는가
C++ 스킬 17: 값에 의한 전달 보다는 상수객체 참조자 (const &) 에 의한 전달 방식을 택하자
함수의 인자로 참조자를 사용하면 복사 생성자로 인해 새로 만들어지는 객체 같은 것이 없기 때문에 호출되는 생성자, 소멸자가 없어진다.
const는 호출부에서 전달한 객체가 바뀌지 않을 것이라는 보장을 해준다.
복사 손실 문제도 해결할 수 있는 장점이 있다.
ㄴ 파생 클래스 객체가 기본 클래스 객체로서 전달될 때 값으로 객체를 전달하면 기본 클래스의 복사 생성자가 호출되고, 파생 클래스 객체로 동작하게 해 주는 특징이 사라진다. (파생 클래스의 함수를 호출할 수 없다)
C++ 스킬 18: 지역 스택 객체에 대한 포인터나 참조자, 힙에 할당한 객체에 대한 참조자, 지역 정적 객체에 대한 포인터나 참조자를 반환하는 일은 그런 객체가 두 개 이상 필요해질 가능성이 있다면 하지말자 ( 메모리 누수와 비정상동작의 위험이 있다.)
C++ 스킬 19: 멤버 함수 몇 개를 내부에서 호출하는 함수는 클래스 밖에서 선언하자. (비멤버 함수로 다른 헤더의 네임스페이스 같은 곳에 )
C++ 스킬 20: 어떤 함수에 들어가는 모든 매개변수 (this 포인터가 가리키는 객체 포함)에 대해 타입 변환을 해 줄 필요가 있다면 그 함수는 비멤버여야 한다. (operator* 의 교환 법칙)
예를 들어 연산 결과 (객체 * 2) 와 (2 * 객체)를 모두 처리하기 위해서는 operator* 멤버 함수를 사용할 수 없다. 비멤버 함수를 사용해야 한다.
C++ 스킬 21: std:swap이 느리게 동작할 여지가 있다면 swap 멤버함수를 제공하자
(클래스 템플릿의 경우) 비멤버 std::swap 함수를 std 네임스페이스가 아닌 다른 네임스페이스에 특수화하는 방법
멤버 함수로 swap을 정의하고 swap 안에서 std::swap을 사용하여 내부 포인터를 swap하는 방법