2010-06-24 7 views
4

C++에서 암시 적 캐스팅 대신 이러한 연산자를 사용하면 어떤 이점이 있습니까?C++ 유형 캐스트 ​​: 명시 적 캐스트를 사용할 때의 이점은 무엇입니까?

dynamic_cast <new_type> (expression) 
reinterpret_cast <new_type> (expression) 
static_cast <new_type> (expression) 

왜, 어떤 상황에서 사용해야합니까? OOP에서 거의 사용되지 않는 것은 사실입니까?

+1

중복? [Regular cast vs. static_cast vs. dynamic_cast] (http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast), [static_cast, dynamic_cast 및 reinterpret_cast는 언제 사용해야합니까? ?] (http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used). – Lazer

답변

7

제공 한 캐스트 목록에서 암시 적 캐스트를 유치하는 데 사용되는 유일한 방법은 static_cast입니다.

dynamic_cast는 수퍼 클래스를 서브 클래스로 다운 캐스트하는 데 사용됩니다. 이것은 암묵적으로 일어날 수 없으며 실제로 OOP에서는 드문 것이 아닙니다. static_cast는 그러한 캐스트에서도 사용될 수 있지만 실행 시간 동안 다운 캐스트가 유효한지 검사하지 않기 때문에 더 위험합니다.

마지막 캐스트 인 reinterpret_cast는 가장 위험하므로 매우주의 깊게 사용해야합니다. 기본적으로 무엇이든 그 안에 무엇이든 넣을 수 있습니다.하지만 프로그래머는 그러한 캐스트가 의미 론적으로 의미가 있는지 확인해야합니다.

+1

정말 빨리 입력하는 법을 배워야합니다 .--( –

3

다른 모든 암시적인 것과 마찬가지로 개발자/검토자가 염두에 두지 않은 논리를 숨기고 버그를 감추고 있습니다.

2

일반적으로 암시 적 변환에 대해보다 엄격한 새로운 컴파일러를 사용하기 시작했기 때문에 무언가가 더 이상 생성되지 않을 때 이러한 유형의 캐스트가 코드에 표시되는 것을 보았습니다. 전환 수. 분명히 그런 상황에서 올바른 것은 다른 방법으로 코드를 변경하는 것입니다!

Dynamic_cast는 다형성이있는 '업 스트림'캐스팅에 사용할 수 있습니다. 그래서 당신이 이런 구조를 가지고 있다면;

자료는 ->은

자료 파생 -> 파생 B

당신이 dynamic_cast는 할 수있다 (B) (b는 Base에 대한 포인터이지만 사실 Derived_B 임);

Derived_B 클래스가 아닌 경우 변환 된 포인터 대신 0이 반환됩니다.

이것은 컴파일 타임이 아닌 런타임에 검사가 수행되기 때문에 static_cast보다 훨씬 느리지 만 의도 된 용도가 다릅니다.

reinterpret_cast는 형식 레이블을 변경하기 때문에 프로토콜/저수준 작업에 유용하지만 펑키 C 스타일 FX (또는 '유형 펀칭'이 일반적으로 호출 됨)를 사용할 수 있지만 아껴서 사용해야합니다.

일반적으로 코드에서 많은 캐스트는 코드 디자인에 문제가 있음을 나타냅니다.

0

reinterpret_cast가 사용되는 상황의 예를 추가하기 만하면됩니다. 라이브러리가 원시 네트워크 패킷에 대한 포인터를 제공한다고 가정 해보십시오. 데이터 구조를 이해하기 위해 구조체를 사용할 수 있습니다. 그런 다음 해당 구조체에 대한 포인터를 캐스팅합니다. 컴파일러가 여기에있는 어떤 것을 수행하고 있는지 또는 단지 메모리에서 읽지 않을 것인지를 확인하는 방법은 없습니다. 실제 상황에서는 먼저 패킷의 크기를 확인하여 구조체가 들어갈 수있는 크기인지 확인하십시오.

아래 코드에서 IP 조각 생성자는 패킷을 가져 와서 해당 포인터를 의미있는 것으로 캐스팅합니다. 아래에 정의를 추가했습니다.

누군가 reinterpret_cast를 사용하는 것이 정당하지 않다고 생각하는 사람이라면 더 나은 방법에 대해 기쁘게 생각합니다.

IPfragment::IPfragment(const byte* const pkt_data) : 
    ethernetHeader(reinterpret_cast< const EthernetHeader* >(pkt_data     ) ) 
    , ipHeader  (reinterpret_cast< const IPheader*  >(pkt_data + ETHER_HEADER_LEN) ) 
    , payload  (reinterpret_cast< const byte*   >(ipHeader     ) 
                  + (ipHeader->ver_hl & 0x0f) *4) 
{ 
} 

이 정의를 다음과 같습니다 C는 ++ 대신 C 스타일 캐스트의 캐스트 사용의 장점

typedef uint8_t byte ; 
typedef uint16_t word ; 
typedef uint32_t dword ; 

#define ETHER_ADDR_LEN 6 // Ethernet addresses are 6 bytes 
#define ETHER_HEADER_LEN 14 // Ethernet headers are 14 bytes 
#define ETHER_TYPE_IP4 8 

struct EthernetHeader 
{ 
    byte etherDestHost[ETHER_ADDR_LEN]; // Destination host address 
    byte etherSrcHost [ETHER_ADDR_LEN]; // Source host address 
    word etherType;      // IP? ARP? RARP? etc 
}; 

/* 4 bytes IP address */ 
struct IPaddress 
{ 
    byte byte1, byte2, byte3, byte4; 
}; 

/* IPv4 header */ 
struct IPheader 
{ 
    byte ver_hl   ;  // Version (4 bits) + Internet header length (4 bits) 
    byte tos    ;  // Type of service 
    word tlen   ;  // Total length 
    word identification ;  // Identification 
    word flags_fo  ;  // Flags (3 bits) + Fragment offset (13 bits) 
    byte ttl    ;  // Time to live 
    byte proto   ;  // Protocol 
    word crc    ;  // Header checksum 
    IPaddress saddr  ;  // Source address 
    IPaddress daddr  ;  // Destination address 
    dword op_pad   ;  // Option + Padding 
}; 

class IPfragment 
{ 
    public: 
    const IPheader*  const ipHeader; 
    const EthernetHeader* const ethernetHeader; 
    const byte*   const payload; 

    IPfragment(const byte* const pkt_data); 

    // rest of code omitted for brevity 
} 
1

한 것은 그들이 쉽게 검색 할 수 있다고합니다. 그들은 또한 C 스타일의 다양한 응용 프로그램을 분리하여 쉽게 식별 할 수있는 냄새를 만들어냅니다.

예를 들어, reinterpret_cast의 grep은 많은 잠재적 인 문제와 나쁜 설계를 쉽게 찾을 수 있지만 C 스타일의 캐스트를 올바르게 식별하는 정규 표현식은 잘못된 캐스트를 식별하기 위해 추가 검사가 필요합니다.

캐스트가 필요한 경우 항상 C++ 캐스트를 사용하고 C 스타일 캐스트는 사용하지 않습니다.

참조 C++ 코딩 표준, 셔터 및 Alexandrescu의, 항목 아주 짧은 대답을 95

2

,이 캐스트의 장점은 코드를 설명하고 특정 기능을 수행한다는 것이다. C 스타일의 캐스트는 모든면에서 강력하며 모든 종류의 실수를 피할 수 있습니다. C에 익숙한 사람들은 캐스트가 쓰는 고통이라는 불평을할지 모릅니다. 그것은 실제로 다른 사람들에 의해 좋은 것으로 간주됩니다. 그것은 프로그래머가 코드 전체에 캐스트를 뿌리는 것을 방해합니다. 이는 문제가있는 코드의 아주 명백한 표시입니다. 마지막으로 텍스트 검색으로 쉽게 찾을 수 있습니다.

관련 문제