c++ 생각하기 2.

반응형

1. 컴파일러가 스스로 하는 암시적인 타입변환.
단일인자 생성자를 통한 암시적 타입변환..... 이녀석의 때문에 생기는 버그는 찾기 어렵다.
미리미리 조심해야지.
단일인자 생성자의 경우에는 explicit 키워드를 사용하자.
하지만 이렇게 해도 명시적인 타입변환은 여전히 허용된다.
명시적인 타입변환까지 막을 필요가 있을까...
말그대로 사용자가 필요해서 대놓고 한다는데.
문제는 몰래하는 암시적변환이지만....

또다른 방법으로는 컴파일러의 암시적 타입변환의 규칙을 교묘히 피해나가는 것이다.
즉, 컴파일러의 암시적 타입변환 규칙에 어긋나게 만드는 것이다.
"사용자 정의 타입변환 함수는 두개 이상 쓰이지 않는다." 라는 것이 있다.
그래서 클래스만 잘 만들어 놓으면 객체생성은 허용하지만 암시적 타입변환은
불가능 하게 만들 수 있다.
그중 하나가 내부클래스의 생성이다.
외부클래스의 단일인자를 내부클래스로 만들어 놓으면 컴파일러의 규책상
한번만 변환하여 찾기 때문에 내부클래스로 다시 형변환하지 못하여
암시적 변환이 일어나지 않는다.

2. 증감 연산자.
그냥..당장 올리고 싶다면 ++value를,
연산후에 올리고 싶다면 value++을 사용했었는데말야...
사실 이녀석들의 내부구현을 보면 특이한 부분이 있다.

UPInt& UPInt::operator++()
{
  *this += 1;
  return *this;
}

const UPInt UPInt::operator++(int)
{
  const UPInt BackupValue = *this;
  ++(*this);
  return BackupValue;
}


전위증가는 참조자 타입을 반환, 후위증가는 const객체를 반환한다.
후위형태에 사용하지 않는 매개변수가 있는데 이는 단지 선위와 후위를 구분하기 위해 붙인것 뿐이다.

그거야.머 그닥 중요한건 아니고..정작 중요한건 후위연산자에서 선위연산자를 호출하도록 되어있다는 점이다.
이는 다른 개발자가 투입되어 코드의 개선이 이루어 질 경우 위 연산자의 동작이 달라질 것을 우려해서
위와같이 만들었다고 볼 수 있다.

3. 연산자 오버로딩
단축평가 처리를 할 때 자주 쓰는 문장이
if( (A<B) || (A>C) ),  if( (A<B) && (A>C) )
이와 같으며 단축평가 처리라고 한다.
앞의 A<B 문구가 거짓이 되면 굿이 뒤의 A>C 처리를 할 필요가 없기 때문이다.

이런 부분에서 이 두녀석을 오버로딩할 때 문제가 생긴다.
내가 원하는건 단축평가 의미구조인데 오버로딩시 함수호출 의미구조로 대체된다.
무슨말인고 하니,오버로딩을 할 경우 전역함수 또는 클래스의 멤버함수로 할 수 있는데
사용할때 if(exp1 && exp2)로 할 경우에 이는 컴파일러에게
if(exp.operator&& (exp2))        // 멤버일 경우
if(operator && (exp1, exp2)      // 전역인 경우
로 보이게 된다.

함수호출이 이루어 질 때 모든 매개변수를 평가해야하므로 단축평가가 이루어 지지 않으며
함수호출에 사용되는 매개변수의 평가를 어떤 순서로 할지에 대해 명확하게 적혀있지 않기 때문
왼쪽exp와 오른쪽exp중 어느것이 먼저 수행될지 모른다.
하지만 단축평가는 왼쪽에서 오른쪽으로 평가되며 이를 알고 쓰는 이들이 존재한다는 것이 문제다.

결론은 &&와 ||은 오버로딩하기에 애매한 문제를 안고있다는 것.
쉼표연산자 역시 어느것이 먼저 수행될지 애매하다.



TAGS.

Comments