static_cast <>와 C 스타일 캐스팅의 차이점은 무엇입니까?


답변:


217

C ++ 스타일 캐스트는 컴파일러에서 확인합니다. C 스타일 캐스트는 런타임에 실패하고 실패 할 수 있습니다.

또한 c ++ 스타일 캐스트는 쉽게 검색 할 수 있지만 c 스타일 캐스트는 검색하기가 어렵습니다.

또 다른 큰 장점은 4 가지 C ++ 스타일 캐스트가 프로그래머의 의도를보다 명확하게 표현한다는 것입니다.

C ++을 작성할 때 C 스타일보다 항상 C ++을 사용합니다.


67
런타임에 실패 할 수있는 유일한 캐스트는 dynamic_cast입니다.
R. Martinho Fernandes

12
C ++ reinterpret_cast <T> (U)는 런타임에 C 스타일 캐스트와 거의 같은 방식으로 실패 할 수 있으며 dynamic_cast <T> (U)가 실패하는 방식과는 상당히 다릅니다.
Christopher Smith

20
일반 C 캐스트 (int)something는 실패 할 수 없습니다 -int로 캐스트 되거나 컴파일러 오류가 발생합니다.
Tomáš Zato-복원 모니카

2
C 캐스트보다 C 캐스트를 더 쉽게 검색하는 이유를 자세히 설명 할 수 있습니까?
Minh Tran

3
@MinhTran C ++ 스타일의 경우 소스 파일을 통해 "cast"키워드를 검색 할 수 있습니다. 그러나 c 스타일 캐스트로 할 수 있습니까?
huangzonghao

176

한마디로 :

  1. static_cast<>() 컴파일 시간 검사 기능을 제공하지만 C 스타일 캐스트는 그렇지 않습니다.
  2. static_cast<>() 더 읽기 쉽고 C ++ 소스 코드의 어느 곳에서나 쉽게 찾을 수 있습니다. C_Style 캐스트는 없습니다.
  3. C ++ 캐스트를 사용하면 의도가 훨씬 더 잘 전달됩니다.

더 많은 설명 :

정적 캐스트는 호환 가능한 유형 간에 변환을 수행합니다 . C 스타일 캐스트와 비슷하지만 더 제한적입니다. 예를 들어 C 스타일 캐스트는 정수 포인터가 문자를 가리 키도록 허용합니다.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

이로 인해 1 바이트의 할당 된 메모리를 가리키는 4 바이트 포인터 (4 바이트 데이터 유형에 대한 포인터)가 생성되므로이 포인터에 쓰면 런타임 오류가 발생하거나 일부 인접한 메모리를 덮어 씁니다.

*p = 5; // run-time error: stack corruption

C 스타일 캐스트와 달리 정적 캐스트를 사용하면 컴파일러에서 포인터 및 포인트 데이터 유형이 호환되는지 확인할 수 있으므로 프로그래머가 컴파일 중에이 잘못된 포인터 할당을 잡을 수 있습니다.

int *q = static_cast<int*>(&c); // compile-time error

C ++ 캐스트에 대한 자세한 설명은이 페이지를 참조 하십시오. 여기를 클릭하십시오.


17
"4 바이트 포인터"대신 "4 바이트 데이터 유형에 대한 포인터"를 의미한다고 생각합니다
iheanyi

그러나 int q = static_cast <int> (c);
TonyParker

3
@TonyParker 그 라인에 문제가 없기 때문입니다.
Braden Best 21

15

C ++ 캐스팅 연산자 비교를 참조하십시오 .

그러나 다양한 캐스팅 작업에 동일한 구문을 사용하면 프로그래머의 의도가 불분명해질 수 있습니다.

또한 큰 코드베이스에서 특정 유형의 캐스트를 찾기가 어려울 수 있습니다.

C 스타일 캐스트의 일반성은 필요한 모든 것이 간단한 변환 인 상황에서 과도 할 수 있습니다. 전력이 다른 여러 주조 작업자를 선택할 수 있으므로 프로그래머가 실수로 잘못된 유형으로 캐스팅하는 것을 방지 할 수 있습니다.


14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}

5
제공하는 솔루션에 대한 설명을 조금 더 추가하여 답변을 더 자세히 설명해 주시겠습니까?
abarisone

1
대답에 따르면 "static_casts"는 유형 변환이 계층 구조 그래프에서 유효한 경로를 따르는 지 확인합니다. 이 특정 예에서는 A와 B가 계층 그래프에서 경로를 형성하므로 A *에서 B *로 또는 B *에서 A *로 캐스트가 허용됩니다. C *가 경로에 없으므로 static_cast는 컴파일 타임 오류를 생성합니다. 참고 : A *에서 B *로 캐스트 할 때 실제 기본 오브젝트에 따라 런타임시 dynamic_cast와 함께 NULL이 발생할 수 있습니다.
Tommy Chen

7

C / C ++의 다양한 캐스트와 C 스타일 캐스트가 실제로하는 일을 설명하는 훌륭한 게시물 : https://anteru.net/blog/2007/12/18/200/index.html

(유형) 변수 구문을 사용하는 C 스타일 캐스팅 최악의 발명품. 다음 순서로 캐스트를 시도합니다 (C ++ 표준, 5.4 expr.cast 단락 5 참조).

  1. const_cast
  2. static_cast
  3. static_cast 다음에 const_cast
  4. reinterpret_cast
  5. reinterpret_cast 다음에 const_cast

5

static_cast컴파일 타임에 변환이 분명히 호환되지 않는 유형 사이에 있지 않은지 확인합니다. 반대로 dynamic_cast런타임에 형식 호환성 검사가 수행되지 않습니다. 또한 static_cast변환이 반드시 안전한 것은 아닙니다.

static_cast 포인터에서 기본 클래스로, 파생 클래스로의 포인터로, 또는 enum에서 int로 또는 float에서 int와 같은 기본 유형간에 변환하는 데 사용됩니다.

의 사용자 static_cast는 변환이 안전한지 확인해야합니다.

C 스타일 캐스트는 컴파일 또는 런타임시 점검을 수행하지 않습니다.


3

static_cast <>를 사용하면 각각 다른 의미를 가진 여러 가지 캐스팅 유형이 있으므로 int에서 double과 같이 "한 유형에서 다른 유형으로 합법적으로 변환하고 있습니다"라고 말할 수 있습니다. 평범한 C 스타일 캐스트는 많은 것을 의미 할 수 있습니다. 업 / 다운 캐스팅입니까? 포인터를 해석하고 있습니까?

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