4. 설계 및 선언
21) 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 하지 말자
지역 객체에 대한 참조자를 반환해서는 절대로 안된다.
함수 내에서 생성된 지역 객체는 함수가 종료되자 마자 사라지기 때문이다.
그렇다면 객체를 힙에 생성해서 반환하는 것은 어떨까?
그러면 delete의 책임이 모호해진다.
최후의 방법으로 정적 객체의 참조자를 반환하는 것은 어떨까?
그러면 스레드 안정성 문제가 생기며 반환 식이 의도와 다르게 동작하는 경우가 왕왕 생긴다.
반환 값이 복사되는 것에 대해 너무 안타깝게 생각하지 말자.
C++에서는 컴파일러가 일부 조건 하에 최적화 메커니즘을 통해 빠르게 동작할 수 있도록 만들어 줄 것이다.
22) 데이터 멤버가 선언될 곳은 private 영역임을 명심하자
public, protected 모두 데이터 멤버를 선언하기에 부적절하다.
먼저 항목 18에서 언급한 것과 같이 멤버에 접근할 때 일관성을 높이기 위해 접근 방법을 모두 함수로 만들자.
또한 접근 방법이 함수로 제한되면 접근 불가, 읽기 전용, 읽기 쓰기 접근 모두 직접 구현할 수 있으니 좋다.
이 데이터 멤버를 추후 계산식으로 대체하거나 할 때에도 편하다.
가장 중요한 점은 private 데이터 멤버로 선언해야만 바로 캡슐화가 된다는 점이다.
데이터가 밖으로 노출되어 사용된 뒤에 관련 코드를 수정하고자 한다면 겉잡을 수 없이 복잡도가 증가하게 된다.
protected 또한 상속되어 파생 클래스에서 사용된 후에는 public과 다를바가 없다.
23) 멤버 함수보다는 비멤버이고 비프렌드인 함수와 더 가까워지자
객체지향 법칙에 사로잡혀 모든 함수를 멤버 함수로 선언하는 것은 썩 좋은 방법은 아니다.
오히려 비멤버 함수가 캡슐화 정도를 높여줄 때가 있다.
만약 비멤버 함수로 관련 기능을 만들게 되면 패키징 유연성이 높아지고, 컴파일 의존도를 낮추게 되고, 관련 클래스의 확장성도 높일 수 있다.
캡슐화란 결론적으로 외부에서 정보를 볼 수 없도록 잘 감싸 변화에 필요한 유연성과 여유가 늘어나게 되는 것이다.
코드를 변경하더라도 영향을 받는 부분이 최소화되기 때문이다.
단, 비 멤버이면서 비 프렌드 함수일때만 이 조건을 충족시킬 수 있다.
비멤버 비프렌드 함수만이 private 멤버 부분을 접근할 수 있는 함수의 개수를 늘리지 않기 때문이다.
주의할 점은, 어떤 함수는 클래스의 비멤버가 되어야 한다는 것이 다른 클래스의 멤버도 되어서는 안된다는 뜻은 아니다.
함수는 다른 별도의 유틸리티 클래스의 정적 멤버 함수가 될 수도 있다.
물론 이러한 경우 C++에서는 같은 네임스페이스 안에 두는 것이 더 자연스럽다.
24) 타입 변환이 모든 매개변수에 대해 적용되어야 한다면 비멤버 함수를 선언하자
operator*와 같이 혼합형 수치 연산을 지원하고 싶다면 다음과 같이 비 멤버 함수를 만들어 컴파일러 쪽에서 모든 인자에 대해 암시적 타입 변환을 수행하도록 내버려두면 된다.
class Rational { ... };
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.dominator() * rhs.dominator());
}
Rational oneForth(1, 4);
Rational result;
// 다음 둘 다 가능합니다.
result = oneForth * 2;
result = 2 * oneForth;
이 때 operator* 는 Rational 클래스의 프렌드 함수가 아니다!
25) 예외를 던지지 않는 swap에 대한 지원도 생각해 보자
내가 만든 클래스에 예외를 던지지 않는 swap을 지원하는 것이 좋다.
멤버 swap와 멤버swap을 호출하는 비멤버 swap을 함께 제공한다
단, std에는 추가하지 말라
(추가중)
'C++ > Effective C++' 카테고리의 다른 글
Effective C++ (31) ~ (35) (0) | 2021.08.24 |
---|---|
Effective C++ (26) ~ (30) (0) | 2021.08.22 |
Effective C++ (16) ~ (20) (0) | 2021.08.14 |
Effective C++ (11) ~ (15) (0) | 2021.08.12 |
Effective C++ (6) ~ (10) (0) | 2021.08.09 |
댓글