2014-04-12 2 views
2

나는 일반적으로 C 스타일의 캐스트가 유해하다고 생각합니다.함수형 캐스트는 유해한 것으로 간주됩니까?

functionThatTakesAWidget((Widget) gizmo); 

C 스타일 캐스트를 사용하여 : 그래서,이 기능을 다음과 같이 호출 할 수있는 클래스를 Widget

class Widget{ 
public: 
    explicit Widget(Gizmo gizmo); 
}; 

을 부여. 또는 함수형 캐스트를 사용하여 쓸 수 있습니다.

functionThatTakesAWidget(Widget(gizmo)); 

그러나 이것은 정확히 같습니다. 그래서 더 좋든 나쁘 든.

functionThatTakesAWidget(static_cast<Widget>(gizmo)); 

을하지만 클래스 Doohickey 주어진 : 난 정말 C 스타일 캐스트를 방지하고 싶었다면 내가 쓸 수

functionThatTakesADoohickey(Doohickey(left_gizmo, right_gizmo)); 

: 나는 글을 피할 수

class Doohickey { 
public: 
    Doohickey(Gizmo left_gizmo, Gizmo right_gizmo); 
}; 

에게 나는 이것이 '캐스트'로 간주되지 않는다고 가정한다. 그러나 이것과 함수형 캐스트의 차이점은 무엇입니까? 왜 이것이 괜찮습니까?하지만 함수형 캐스트는 그렇지 않습니다. C 스타일 캐스트를 피하기위한

+0

함수 스타일 캐스트는 실제로 캐스트가 아니며 생성자 또는 유형 변환 연산자 호출입니다. – EJP

+0

@EJP'(위젯) 기즈모'는'위젯 (기즈모) '과 정확히 동일합니다. – user3502661

+0

가변 위치를 다른 유형으로 재 해석하고 생성자 또는 유형 변환을 유발하는 C 스타일 형변환에는 차이가 있습니다. C 스타일 캐스트는 C 프로그래밍 언어의 종속 변수이며 특정 변수 또는 메모리 위치가 특정 유형임을 컴파일러에 알리는 것입니다. 변환을 수행하는 메소드를 제공하거나 컴파일러가 변환을 수행 할 일련의 메소드를 찾을 수있는 경우 C++에서 수행하는 변환이 없습니다. C 스타일 캐스트는이 차이로 인해 훨씬 ​​안전하지 않습니다. –

답변

0

이유는 다음과 같습니다

  • 따라서 다른 유형이 실제로하지 않습니다 확인하고, 주조의 종류는 어떻게되는지에 대한 명시된다.
  • 캐스트를 쉽게 찾을 수 있습니다.

실제로 기능 스타일의 캐스트가 더 안전 해 보이지만 실제로는 C 스타일의 캐스트가 변장되어 있으므로 실제로 아무 것도 추가하지 않습니다.

명백한 뒤에있는 이유는 자동으로 (때로는) 잘못된 것을 수행하는 대신 컴파일러가 가정을 수행하도록하는 것입니다.
IMHO, 일부 순수 주의자들은 열심히 멀리갑니다.

+4

§5.2.3/1 : "간단한 형식 지정자 (7.1.6.2) 또는 typename 지정자 (14.6) 다음에 괄호로 묶인 expression-list 다음에 식 목록이 있으면 지정된 형식의 값이 생성됩니다. 식 목록 형식 변환 식은 해당 캐스트 표현식 (5.4)과 동일합니다 (정의가 정의되어 있고 의미가 정의 된 경우). 그게 내게 더 제한적인 것처럼 들리는 것은 아닙니다. –

+0

@ Jerry : 기능 스타일의 캐스트를 선호하는 의사가 적어도 있긴하지만. 테스트를 거쳐 실제로는 없습니다. – Deduplicator

0

Widget(gizmo)을 "C 스타일 캐스트"라고하지 않겠습니다. C에서는 어쨌든 구조체 유형으로 변환 할 수 없습니다. "C 스타일 캐스트"의 주요 문제점은 포인터 또는 참조 캐스트가 발생하는 경우입니다. 그런 다음 C 스타일의 캐스트가 모호하거나 정의되지 않은 동작을 일으킬 수 있습니다.

가치 변환은 내 견해로는 참조 형 변환과는 다른 개념이며 두 가지 모두에 대해 동일한 규칙을 사용할 필요가 없습니다.

코드는 Widget 임시 생성자이며 생성자에 gizmo을 전달합니다. 나는 static_cast 버전이 오도 된 것이라고 생각하고 Widget(gizmo)은 문제가 없다.

알아두기 functionThatTakesADoohickeyGizmo 또는 std::initializer_list<Gizmo>이 걸리게 할 수 있습니다.

0

나는 믿습니다

C c; 
(A)c 

는 캐스팅 연산자 "C : 운영자 A를()"를 호출합니다. C가 제공되지만 A가 필요하면 호출 할 수 있습니다.예를 들어 "A : A (const를 & C)"또한

void f(A const&) { ... } 
f(c); 

,

A(c) 

생성자를 호출합니다.

캐스트 연산자를 정의하지 않으면 C++에서 A를 얻기 위해 암시 적으로 생성자를 호출 할 수 있다고 생각합니다. 때때로 이것은 큰 재앙입니다 (이 생성자가 이혼을 위해 하드 드라이브와 파일을 포맷한다고 가정 해 봅시다) .

class A { 
public: 
    explicit A(const& C); // Don't call this when asking to cast to an A. 
} 

및 "기능 스타일은"캐스트 (생성자를 호출하여) 이혼을 제기 할 수 있습니다, 그들은 해로운 것으로 간주하고 있기 때문에

static_cast<A>(C); // Really, just call the casting operator, don't implicitly cast. 

: 그래서 두 가지 요법이있다.

아무 문제가 없습니다 :

f(c1,c1) 

보통 '유형으로 객체의 유형을 설정'의미 '캐스트'로 생각하지 않을 일반적으로 A. 사람들을 얻을 수 있습니다. 일반적으로

당신은 쓸 것이다 : 얻을 기능 //

무효 AA (CONST & C를) {...}

D = A (C)

혼란 스럽기 때문에.

(? 클래스 또는 함수) 그리고 당신은 작성하지 않으려는 것 :

무효 TOA (const를 & C) {...}을

단순히이 기능이 더 잘 때문에 A 클래스에 캡슐화됩니다. 그러나 그렇지 않으면 특별히 해롭지 않습니다.

관련 문제