스토리텔링 개발자

[More Effective C++] 21. 오버로딩으로 암시적 변환 막기 본문

개발/More Effective C++

[More Effective C++] 21. 오버로딩으로 암시적 변환 막기

김디트 2024. 8. 28. 10:44
728x90

항목 21 : 오버로딩은 불필요한 암시적 타입 변환을 막는 한 방법이다.

 

 

 

암시적 변환
// Unlimited Precision Integer
class UPInt
{
public:
    UPInt();
    UPInt(int value);
    ...
};

const UPInt operator+(const UPInt& lhs, const UPInt& rhs);

// 일반적인 사용법
UPInt upi1, upi2;
...
UPInt upi3 = upi1 + upi2;

// 이렇게 사용하게 된다면?
upi3 = upi1 + 10;
upi3 = 10 + upi2;
  • UPInt는 int를 생성자로 받아들이기 때문에 암시적 변환이 일어나 UPInt 타입을 임시 객체로 생성한다.
    • 하지만, 임시 객체는 리소스의 낭비이다.
  • 사실 이 코드의 목적은 타입변환이 아니라 UPInt와 int 타입 인자에 대해 operator+를 호출하는 것이다.
    • 암시적 타입변환은 한 가지 답이 될 수 있겠지만, 다른 방법도 가능할 것이다.

 

 

 

오버로딩
const UPInt operator+(const UPInt& lhs, const UPInt& rhs);
cosnt UPInt operator+(const UPInt& lhs, int rhs);
const UPInt operator+(int lhs, const UPInt& rhs);

UPInt upi1, upi2;

// 이제 아래 코드 모두에 임시 객체는 생성되지 않는다.
UPInt upi3 = upi1 + upi2;
upi3 = upi1 + 10;
upi3 = 10 + upi2;
  • 그렇지만, 신나게 오버로딩 하다 보면..
const UPInt operator+(int lhs, int rhs); // 에러!!
  • 오버로딩 규칙
    • 오버로딩 되는 연산자 함수는 반드시 최소한 한 개의 사용자 정의 타입을 매개변수로 가져야 한다.
    • int는 사용자 정의 타입이 아니기 때문에, 위의 오버로딩은 컴파일 에러.
    • 위 규칙이 없었다면.. 기존 연산자의 의미가 마음껏 바뀔 수 있을 것이다..

 

 

 

정리
  • 당연하지만 오버로딩을 통한 임시 객체 생성을 막는 기법은 연산자 이외의 함수에도 사용할 수 있다.
    • 예를 들면 char* 포인터와 string 객체를 함께 받는 함수
    • 예를 들면 complex(항목 35 참조) 등의 수 클래스에서 int, double 등의 기본 제공 타입을 섞어 쓰는 경우.
  • 하지만 80-20 법칙(항목 16 참조)을 고려해서 효율에 특별한 향상이 있다고 생각되는 지점이 아닌 한 굳이 오버로딩 할 필요는 없을 것이다.
728x90
Comments