your programing

static_cast를 사용하는 이유

lovepro 2020. 10. 2. 23:01
반응형

static_cast를 사용하는 이유(int) x 대신 (x)?


static_castC 스타일이나 단순 함수 스타일 캐스팅보다 기능이 더 선호되어야한다고 들었습니다 . 이것이 사실입니까? 왜?


주된 이유는 고전적인 C 캐스트는 우리가 부르는 사이에 구분하지 않습니다이다 static_cast<>(), reinterpret_cast<>(), const_cast<>(),와 dynamic_cast<>(). 이 네 가지는 완전히 다릅니다.

A static_cast<>()는 일반적으로 안전합니다. 언어에 유효한 변환이 있거나이를 가능하게하는 적절한 생성자가 있습니다. 약간 위험한 경우는 상속 된 클래스로 캐스트 할 때뿐입니다. 객체가 실제로 해당 언어 (객체의 플래그와 같은)의 외부를 통해 주장하는 하위 항목인지 확인해야합니다. A dynamic_cast<>()는 결과를 확인 (포인터)하거나 가능한 예외를 고려 (참조)하는 한 안전합니다.

반면에 A reinterpret_cast<>()(또는 a const_cast<>())는 항상 위험합니다. 당신은 컴파일러에게 "저를 믿으세요 : 나는 이것이 a처럼 보이지 않는다는 것을 압니다 (이것은 그것이 변하지 않는 것처럼 foo보임), 그러나 그것은 그렇습니다"라고 말합니다.

첫 번째 문제는 크고 분산 된 코드 조각을보고 모든 규칙을 알지 않고는 C 스타일 캐스트에서 어떤 것이 발생할지 알 수 없다는 것입니다.

다음을 가정 해 보겠습니다.

class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;

CMyBase  *pSomething; // filled somewhere

이제이 두 가지는 같은 방식으로 컴파일됩니다.

CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked

pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
                                     // Safe; as long as we checked
                                     // but harder to read

그러나 거의 동일한 코드를 보겠습니다.

CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert

pOther = (CMyOtherStuff*)(pSomething);            // No compiler error.
                                                  // Same as reinterpret_cast<>
                                                  // and it's wrong!!!

보시다시피, 관련된 모든 클래스에 대해 많이 알지 않고 두 상황을 쉽게 구별 할 수있는 방법은 없습니다.

두 번째 문제는 C 스타일 캐스트를 찾기가 너무 어렵다는 것입니다. 복잡한 표현에서는 C 스타일 캐스트를보기가 매우 어려울 수 있습니다. 완전한 C ++ 컴파일러 프런트 엔드없이 C 스타일 캐스트 (예 : 검색 도구)를 찾는 데 필요한 자동화 도구를 작성하는 것은 사실상 불가능합니다. 반면에 "static_cast <"또는 "reinterpret_cast <"를 검색하는 것은 쉽습니다.

pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
      // No compiler error.
      // but the presence of a reinterpret_cast<> is 
      // like a Siren with Red Flashing Lights in your code.
      // The mere typing of it should cause you to feel VERY uncomfortable.

즉, C 스타일 캐스트가 더 위험 할뿐만 아니라 올바른지 확인하기 위해 모두 찾는 것이 훨씬 더 어렵습니다.


실용적인 팁 : 프로젝트를 정리하려는 경우 소스 코드에서 static_cast 키워드를 쉽게 검색 할 수 있습니다.


간단히 말해서 :

  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

Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.

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

In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.

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

Read more on:
What is the difference between static_cast<> and C style casting
and
Regular cast vs. static_cast vs. dynamic_cast


The question is bigger than just using wither static_cast or C style casting because there are different things that happen when using C style casts. The C++ casting operators are intended to make these operations more explicit.

On the surface static_cast and C style casts appear to the same thing, for example when casting one value to another:

int i;
double d = (double)i;                  //C-style cast
double d2 = static_cast<double>( i );  //C++ cast

Both of these cast the integer value to a double. However when working with pointers things get more complicated. some examples:

class A {};
class B : public A {};

A* a = new B;
B* b = (B*)a;                                  //(1) what is this supposed to do?

char* c = (char*)new int( 5 );                 //(2) that weird?
char* c1 = static_cast<char*>( new int( 5 ) ); //(3) compile time error

In this example (1) maybe OK because the object pointed to by A is really an instance of B. But what if you don't know at that point in code what a actually points to? (2) maybe perfectly legal(you only want to look at one byte of the integer), but it could also be a mistake in which case an error would be nice, like (3). The C++ casting operators are intended to expose these issues in the code by providing compile-time or run-time errors when possible.

So, for strict "value casting" you can use static_cast. If you want run-time polymorphic casting of pointers use dynamic_cast. If you really want to forget about types, you can use reintrepret_cast. And to just throw const out the window there is const_cast.

They just make the code more explicit so that it looks like you know what you were doing.


static_cast means that you can't accidentally const_cast or reinterpret_cast, which is a good thing.


  1. Allows casts to be found easily in your code using grep or similar tools.
  2. Makes it explicit what kind of cast you are doing, and engaging the compiler's help in enforcing it. If you only want to cast away const-ness, then you can use const_cast, which will not allow you to do other types of conversions.
  3. Casts are inherently ugly -- you as a programmer are overruling how the compiler would ordinarily treat your code. You are saying to the compiler, "I know better than you." That being the case, it makes sense that performing a cast should be a moderately painful thing to do, and that they should stick out in your code, since they are a likely source of problems.

See Effective C++ Introduction


It's about how much type-safety you want to impose.

When you write (bar) foo (which is equivalent to reinterpret_cast<bar> foo if you haven't provided a type conversion operator) you are telling the compiler to ignore type safety, and just do as it's told.

When you write static_cast<bar> foo you are asking the compiler to at least check that the type conversion makes sense and, for integral types, to insert some conversion code.


EDIT 2014-02-26

I wrote this answer more than 5 years ago, and I got it wrong. (See comments.) But it still gets upvotes!


C Style casts are easy to miss in a block of code. C++ style casts are not only better practice; they offer a much greater degree of flexibility.

reinterpret_cast allows integral to pointer type conversions, however can be unsafe if misused.

static_cast offers good conversion for numeric types e.g. from as enums to ints or ints to floats or any data types you are confident of type. It does not perform any run time checks.

dynamic_cast on the other hand will perform these checks flagging any ambiguous assignments or conversions. It only works on pointers and references and incurs an overhead.

There are a couple of others but these are the main ones you will come across.


static_cast, aside from manipulating pointers to classes, can also be used to perform conversions explicitly defined in classes, as well as to perform standard conversions between fundamental types:

double d = 3.14159265;
int    i = static_cast<int>(d);

참고URL : https://stackoverflow.com/questions/103512/why-use-static-castintx-instead-of-intx

반응형