일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- implicit conversion
- 반복자
- 게임
- 티스토리챌린지
- 영화
- c++
- reference
- 루아
- Effective c++
- 예외
- 영화 리뷰
- 비교 함수 객체
- resource management class
- Smart Pointer
- 상속
- 스마트 포인터
- 오블완
- exception
- 참조자
- effective stl
- 암시적 변환
- lua
- 언리얼
- Vector
- UE4
- virtual function
- 메타테이블
- operator new
- more effective c++
- 다형성
Archives
- Today
- Total
스토리텔링 개발자
[More Effective C++] 7. operator&& / operator|| / operator, 본문
개발/More Effective C++
[More Effective C++] 7. operator&& / operator|| / operator,
김디트 2024. 8. 7. 11:36728x90
항목 7 : &&, ||, 혹은 , 연산자는 오버로딩 대상이 절대로 아니다
단축 평가(short-circuit)
- C와 마찬가지로 C++ 역시 복합적인 불린 표현식을 평가할 때 단축 평가 처리를 할 수 있다.
- 즉, 표현식의 일부가 참, 거짓임이 판명되면, 그 이후의 표현식은 무시하고 평가를 중단한다.
// 1.
char* p;
// 이 경우, p != 0 이 거짓으로 판명되면 strlen이 호출될 걱정을 할 필요가 없다.
// 즉, null 포인터에 대한 strlen 호출이 되지 않음을 가정하고 작성한 코드이다.
// null 포인터에 대한 strlen 호출은 미정의 사항이기 때문이다.
if((p != 0) && (strlen(p) > 10))
{ ... }
// 2.
int rangeCheck(int index)
{
// index가 lowerBound보다 작으면 upperBound와 비교될 일이 없다.
if((index < lowerBound) || (index > upperBound)) ...
}
operator&&와 operator|| 함수 오버로딩
- 이 두 연산자의 기능을 바꾼다는 것은 아래와 같은 의미이다.
- 본래의 단축평가 의미구조(short-circuit semantics)를 함수호출 의미구조(function call semantics)로 대체한다.
if(expression1 && expression2) ...
// &&, || 연산자를 재정의하면
// 위의 if 문은 컴파일러에게 아래처럼 보인다는 뜻이다.
// operator&&가 멤버 함수일 경우
if(expression1.operator&&(expression2)) ...
// operator&&가 전역 함수일 경우
if(operator&&(expression1, expression2)) ...
함수 호출이 단축평가와 다른 점
- 함수 호출이 이루어질 때는 모든 매개변수를 평가한다.
- 즉 단축평가가 이루어지지 않는다.
- C++ 명세서에는 함수 호출에 사용되는 매개변수의 평가 순서가 명시되어 있지 않다.
- 즉, 순서대로 평가된다는 보장이 없다.
- 허나 단축평가는 항상 왼쪽에서 오른쪽으로 평가한다.
쉼표 연산자
- 표현식을 꾸미는 용도로 사용한다.
void reverse(char s[])
{
for(int i = 0, j = strlen(s) - 1 ; i < j; ++i, --j) // 쉼표 연산자 사용
{
int c = s[i];
s[i] = s[j];
s[j] = c;
}
}
- 쉼표 연산자의 규칙
- 왼쪽에서 오른쪽으로 평가한다.
- 쉼표가 쓰인 전체 표현식의 결과는 오른쪽에 있는 표현식의 값이다.
- 즉, (++i, --j)의 경우 결과값은 --j의 값이다.
- 쉼표 연산자 오버로딩의 문제점
- 쉼표 연산자가 전역 함수로 만들어진 경우
- 왼쪽 표현식이 오른쪽 표현식보다 먼저 평가된다고 보장할 수 없다.
- 쉼표 연산자가 멤버 함수로 만들어진 경우
- 왼쪽 피연산자가 먼저 평가된다는 확신을 할 수 없다.
- 쉼표 연산자가 전역 함수로 만들어진 경우
오버로딩 할 수 없는 연산자의 종류
. | .* | :: | ?: |
new | delete | sizeof | typeid |
static_cast | dynamic_cast | const_cast | reinterpret_cast |
오버로딩 가능한 연산자의 종류
operator new | operator delete |
operator new[] | operator delete[] |
+ | - | * | / | % | ^ | & | | | ~ |
! | = | < | > | += | -= | *= | /= | %= |
^= | &= | |= | << | >> | >>= | <<= | == | != |
<= | >= | && | || | ++ | -- | , | ->* | -> |
() | [] |
- new, delete 연산자의 경우 (항목 8 참조)
결론
- 단순히 오버로딩 가능하다고 오버로딩을 하진 말 것.
- && || , 연산자는 아무리 용을 써도 원래 연산자처럼 동작하도록 만들 수가 없기 때문이다.
참조
728x90
'개발 > More Effective C++' 카테고리의 다른 글
[More Effective C++] 9. 자원 관리 객체(RAII) (0) | 2024.08.09 |
---|---|
[More Effective C++] 8. new / delete 연산자와 operator new / delete (0) | 2024.08.08 |
[More Effective C++] 6. operator++ / operator-- (0) | 2024.08.06 |
[More Effective C++] 5. 암시적 변환 지양하기 (0) | 2024.08.05 |
[More Effective C++] 4. 불필요한 기본 생성자 미제공하기 (0) | 2024.08.04 |
Comments