KoreanFoodie's Study
Effective C++ | 항목 20 : '값에 의한 전달' 보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다 본문
Tutorials/C++ : Advanced
Effective C++ | 항목 20 : '값에 의한 전달' 보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다
GoldGiver 2022. 10. 25. 16:12
C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!
항목 20 : '값에 의한 전달' 보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다
핵심 :
1. '값에 의한 전달' 보다는 '상수 객체 참조자에 의한 전달' 을 선호하자. 대체적으로 효율적일 뿐만 아니라 복사손실 문제까지 막아준다.
2. 이번 항목에서 다룬 법칙은 기본제공 타입 및 STL 반복자, 그리고 함수 객체 타입에는 맞지 않는다. 이들에 대해서는 '값에 의한 전달' 이 더 적절하다.
기본적으로 C++ 는 함수로부터 객체를 전달받거나 전달할 때 '값에 의한 전달(pass-by-value)' 방식을 사용한다. 이러한 '사본'을 만들어내는 원천은 복사 생성자인데, 이는 매우 고비용이라는 단점이 있다. 또한 복사 손실문제(slicing problem) 도 발생할 수 있는데, 다음 예시를 보자.
class Window
{
public:
...
std::string name() const;
virtual void display() const;
};
class WindowWithScrollBars: public
{
public:
virtual void display() const;
};
...
WindowWithScrollBars wwsb;
// 이 녀석을 호출하면..?
printNameAndDisplay(wwsb);
// 저런! 매개변수 전달 과정에서 '복사 생성자'가 호출되어
// WindowWithScrollBars 의 display() 함수가 잘려나간다!
void printNameAndDisplay(Window w)
{
std::cout << w.name();
// 에러! Window 클래스는 display() 함수가 없다
w.display();
}
// 이렇게 고치면 기본 클래스의 성질을 그대로 갖는다
void printnameAndDisplay(const Window& w)
{
...
}
객체의 크기가 작고 복사 생성자가 비싸지 않다고 무조건 '값에 의한 전달'을 사용하는 것은 좋지 못한 선택이다.
예를 들어, double 은 레지스터에 넣어 주지만, double 하나로 만들어진 사용자 정의 타입 객체는 레지스터에 넣지 않기도 한다. 이런 경우, 차라리 참조에 의한 전달을 사용해 포인터(참조자가 포인터로 구현된다)를 레지스터에 넣도록 만드는게 더 낫다.
정리하면, '값에 의한 전달'이 저비용이라고 가정해도 괜찮은 유일한 타입은 기본제공 타입, STL 반복자, 함수 객체 타입, 이렇게 세 가지 뿐이다.
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective C++ | 항목 22 : 데이터 멤버가 선언될 곳은 private 영역임을 명심하자 (0) | 2022.10.25 |
---|---|
Effective C++ | 항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자 (0) | 2022.10.25 |
Effective C++ | 항목 19 : 클래스 설계는 타입 설계와 똑같이 취급하자 (0) | 2022.10.25 |
Effective C++ | 항목 18 : 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자 (0) | 2022.10.25 |
Effective C++ | 항목 17 : new 로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 (0) | 2022.10.25 |
Comments