C 스타일 캐스트 또는 C ++ 스타일 캐스트


21

그래서, 당신은 무엇을 사용합니까?

int anInt = (int)aFloat;

또는

int anInt = static_cast<int>(aFloat);
// and its brethren

그리고 더 중요한 이유는 무엇입니까?

답변:


45

먼저, 해당 행이 동일하지 않다는 것을 이해하십시오 .

int* anInt = (int*)aFloat; // is equivalent to

int* anInt = reinterpret_cast<int*>(aFloat); 

여기서 일어나는 일은 프로그래머가 컴파일러에게 캐스트를 할 수있는 모든 작업을 수행하도록 요청한다는 것입니다.

static_cast를 사용하면 변환 할 "안전한"기본 유형 만 요청하므로 reinterpret_cast는 원하는 오브젝트 레이아웃을 지정된 오브젝트의 메모리에 맵핑하여 원하는 것으로 변환 할 수 있기 때문에 차이가 중요합니다.

따라서 "필터"가 동일하지 않기 때문에 컴파일러 (또는 런타임 impl. dynamic_cast를 사용하는 경우)를 사용하여 잘못된 위치를 알려주는 경우 특정 캐스트를 사용하는 것이 C 캐스트를 사용하는 것보다 명확하고 안전합니다. C 캐스트 및 reinterepret_cast를 피하십시오.

더 명확 해 졌으므로 static_cast, reinterpret_cast, const_cast 및 dynamic_cast가보다 쉽게 검색 할 수 있습니다.

그리고 궁극적 인 요점 : 그들은 추악 합니다. 그것은 원했다. 잠재적으로 버그가있는 코드, 코드 냄새, 버그를 생성 할 수있는 명백한 "트릭"은보기 흉한 모양과 관련이있을 때 쉽게 추적 할 수 있습니다. 나쁜 코드는 못 생겼습니다 .

"디자인에 의한 것"입니다. 이를 통해 개발자는 자신이 더 잘 수행 할 수있는 위치 (실제로 필요하지 않은 경우 캐스트를 완전히 피함으로써)와 괜찮은 위치를 알 수 있지만 코드에서 추악한 것으로 "표시"하여 코드에 "문서화 된"위치를 알 수 있습니다.

새로운 스타일의 캐스트를 도입 한 두 번째 이유는 프로그램에서 C 스타일 캐스트를 찾기가 매우 어렵다는 것입니다. 예를 들어 일반 편집기 나 워드 프로세서를 사용하여 캐스트를 편리하게 검색 할 수 없습니다. C 스타일 캐스트의 이처럼 보이지 않는 부분은 잠재적으로 손상을 입기 때문에 특히 유감입니다. 못생긴 작업은 못생긴 구문 형태를 가져야합니다. 이러한 관찰은 새로운 스타일의 캐스트 구문을 선택하는 이유의 일부였습니다. 또 다른 이유는 새로운 스타일의 캐스트가 템플릿 표기법과 일치하기 때문에 프로그래머가 자신의 캐스트, 특히 런타임 검사 캐스트를 작성할 수 있기 때문입니다.

static_cast는 너무 추하고 입력하기가 상대적으로 어렵 기 때문에 하나를 사용하기 전에 두 번 생각할 가능성이 더 큽니까? 캐스트는 현대 C ++에서 실제로 피할 수 있기 때문에 좋습니다.

출처 : Bjarne Stroustrup (C ++ 제작자)


2
몇 가지 포인트가 더 있으면 이것을 공감하지만 불행히도 나는 할 수 없습니다. c 스타일 캐스트는 reinterpret_cast와 동일하지 않습니다. 고려하십시오 reinterpret_cast<int>(double);. c 스타일 캐스트를 사용하여 double을 int로 캐스트 할 수는 있지만 reinterpret_cast를 사용하여 수행 할 수는 없습니다. Timbo가 이미이 사실을 지적한 것을 보았습니다. 문제를 해결하겠다고 말했지만 4 년 후에도 여전히 올바르지 않습니다. 캐스트를 사용해야하는 완벽한 이유가 있기 때문에 그래도 수정 된 경우 여전히 공감 할 것입니다. 더 나은 대답은 다음과 같습니다. stackoverflow.com/a/332086/3878168
Yay295

36

C ++ 캐스트는 더 제한적입니다 (따라서 의도를 더 잘 표현하고 코드 검토를 더 쉽게 만듭니다). 필요한 경우 검색하기가 훨씬 쉽습니다.


10
... 그리고 그들은 당신이 원하는 것을 할 가능성이 더 큽니다. ;-)
Macke 2016 년

7
그리고 그들은 입력하기가 훨씬 더 많아서 캐스트가 필요없는 유형을 정확하게 얻을 수있는 또 다른 이유를 제공합니다.
Michael Kohne

7
그리고 그것들은 추악한 기능으로, 코드에서 개선이 필요하거나 문서가 필요할 수있는 특별한 경우가있는 곳을 분명하게 보여줍니다. -편집 : 와우, 나도이 질문에 답했다는 것을 발견했다! XD
Klaim

이제 왜 그들을 검색하고 싶습니까?
중복 제거기

@Deduplicator 코드베이스에서 캐스트가 어디에서 발생하는지 알고 싶은 많은 이유가 있습니다. 예를 들어 캐스팅과 관련 될 수있는 버그를 사냥 할 때 (특히 크로스 플랫폼 개발을 수행 할 때).
Klaim

13

옵션 C : "C ++ 스타일"캐스트 (시공과 구분할 수 없기 때문에) :

int anInt = int(aFloat);

또는:

int anInt(aFloat);

잘 이해되는 프리미티브가있는 사소한 경우를 제외하고는 C 스타일 캐스트보다 x_cast <s를 사용하는 것을 선호합니다. 세 가지 이유가 있습니다.

  • 프로그래머가 수행하려는 작업을 더 좁게 정의합니다.

  • C 스타일 캐스트가 수행 할 수없는 동작 (특히 다중 상속 체인의 분기간에 크로스 캐스트 할 수있는 dynamic_cast <>의 경우)을 수행 할 수 있습니다.

  • 그들은 추악 합니다. 그들은 프로그래머가 타입 시스템에 대해 작업하고 있다고 큰 소리로 선언합니다. 이 경우 좋은 일입니다.


7

C로 코드를 작성하는 경우 C 캐스트를 사용하십시오. C ++로 작성하는 경우 C ++ 캐스트를 사용하십시오.

대부분의 캐스팅은 적절한 유형 안전을 깨뜨리는 반면 C ++은 더 제한적이므로 C 캐스팅보다 약간 안전하지 않습니다.

과부하를 강제로 (T *) NULL을 사용하여 누군가를 용납 할 수 있습니다 ...


7

C / C ++ 스타일 캐스트에 대한 몇 가지 규칙이 있습니다.

  1. 지-적용하는 const를 수행해야 항상 를 사용const_cast . 명백한 이유로. 슬프게도, 키보드가 닿아 프로그래머의 손가락을 깰 수있는 const를 적용하는 것에 대한 나의 규칙은 승인되지 않았습니다.
  2. 프로그래머가 금속에 접근 할 때 발생하는 비트 조작 스타일의 스 나니 건은 모두 사용해야 reinterpret_cast합니다. 그것은 실제로 C가 가지고 있지 않은 일종의 캐스트입니다.이 정수의 비트는 실제로 플로트의 비트라고 가정하십시오. 이렇게하면 불쾌감을 피할 수 (int)(*(int*)(&floatVar))있습니다.
  3. "dynamic_cast " 다형성 클래스 계층 구조 및 디자인을 중지하고 다시 평가하십시오. 해당 단어를 삭제할 수있을 때까지 클래스 계층 구조 디자인을 계속 재평가하십시오.
  4. 귀찮게하지 마십시오 static_cast.

# 4의 추론은 단순히 중요하지 않다는 것입니다. 다른 규칙에 맞지 않는 상황은 명백하거나 실제로 저수준입니다. int-to-float와 같은 간단한 유형의 변환을 잘 이해하면 특별한 구문이 필요하지 않습니다. 그리고 만약 당신이 뭔가 깊고 못생긴 용기에 빠져 있다면, 당신은 뭔가 깊고 못생긴 용기에 빠져 있습니다. 이빨, 발톱 및 불이 이미 많은 것을 버렸기 때문에 "여기에 용이있다"는 사실에 주목할 필요가 없습니다.


1
dynamic_cast완벽하게 유효한 도구입니다. 거의 유용하지는 않지만, 글로벌 변수와 같은 것은 사탄과는 거리가 멀다. 그러나 주로 C 스타일 캐스트의 사용 여부에 관한 질문에 대답하지 않았기 때문에 나는 당신을 하향 투표했습니다 .
DeadMG

2
@DeadMG : C 스타일 캐스트에 대해 이야기했습니다. 마지막 단락 전체는 static_cast를 선호하는 C 스타일 캐스트를 정당화합니다.
Nicol Bolas 2016 년

"슬프게도, 키보드가 닿아 프로그래머의 손가락을 깰 수있는 const를 적용하는 것에 대한 나의 규칙은 승인되지 않았습니다." 기술적으로 컴파일러가 그렇게하는 것이 합법적입니다. 컴파일러가 귀신을 코에서 날려 버리는 것도 합법적입니다 .
Pharap


3

그것은 당신이 무슨 말을하는지 알기 때문에 내가 어떤 언어로 작업하고 있는지에 달려 있습니다. C로 프로그래밍하는 경우 C 기능을 최대로 사용하려고 시도하지만 C ++에서 프로그래밍하는 경우 C ++ 기능을 최대로 사용합니다. 그들은 코드를 "휴대용으로 만들지 않는다"고 말하지만, 상관하지 않는다고 말하고, C ++이고 C ++로 프로그래밍하고 있으며, 코드를 컴파일하려면 완전히 C ++ 호환 컴파일러가 필요합니다. 그렇지 않으면 다른 것으로 작업하고 있습니다. 처음에.


C ;-)에서 C ++ 스타일 캐스트를 사용하는 것은 실제로 작동하지 않습니다.
Steve314

3

static_cast 등은 템플리트에서 사용될 때 C 스타일 캐스트의 문제점으로 인해 발명되었습니다. 템플릿을 작성 중이거나 나중에 코드로 템플릿으로 변환 될 수있는 경우 C ++ 스타일 캐스트를 사용하는 것이 좋습니다. 그 이유는 C ++ 스타일 캐스트가 표현 의도를보다 잘 나타 내기 때문에 C 스타일 캐스트가 잘못된 일을하는 경우 (예 : 특정 유형을 템플릿 매개 변수로 제공) 예상 결과를 제공하기 때문입니다.

그 외에는 C ++ 스타일 캐스트를 사용해야한다고 말하면 필요합니다 .dynamic_cast가 가장 일반적이지만 일상적인 것은 아닙니다.

다른 것, C 스타일 캐스트는 약간 덜 혼란스럽고 가독성을 높이거나 요즘 독자가 캐스트 스타일에 얼마나 익숙한 지에 따라 달라질 수 있습니다. 내 생각에는 중요하지 않지만 대부분 개인 취향의 것들이지만 C 스타일을 좋아하지 않는 사람들도 놀라지 마십시오.

마지막 참고 사항-캐스트가 너무 많아서 이것이 큰 문제라면 다른 일을하고있을 것입니다. 경우에 따라 예외가 있지만 대부분의 고급 코드에는 많은 캐스트가 필요하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.