2013-07-29 27 views
15

이 작업을 수행 할 수 있습니까?C 스타일 캐스트를 사용하여 파생 클래스를 개인 기본 클래스로 캐스팅 할 수 있습니까?

class A { ... }; 

class B : private A 
{ 
    const A &foo() const 
    { 
     return *((const A *)this); 
    } 
}; 

나는 기본 클래스에서 개인적으로 상속하는 서브 클래스를 가지고 기본 클래스의 공개 버전으로 캐스팅 할 수 있습니까? 나는 가상의 방법이 없다면 이것을 할 수 있을까?

내 생각은 그렇습니다.하지만 안전하고 휴대 가능하도록하고 싶습니다.

+0

은 ... – Nbr44

+0

나는 그 "개인"상속의 의미 다음을 수행 할 수있는 좋은 일이되지 않을 것 말할 것입니다. 이런 종류의 상속은 "상식으로 구현된다"는 것을 의미하지만 공개 상속은 "is-a"관계입니다. – JBL

+0

왜 처음부터이 끔찍한 해킹을 원하겠습니까? –

답변

14

예를 수행 할 수 있습니다 표준의 §5.4/7 :

(선택적에 const_cast 작동을합니다) 을 수행 할 수있는 다음 static_cast와 reinterpret_cast 작업 명시의 캐스트 표기법을 사용하여 기본 클래스 형태에 액세스 할 수없는 경우에도, 변환 입력

포인터 파생 된 클래스 타입의 객체 또는 파생 클래스 형식의 좌변에 명시 적 명백한 포인터 또는 레퍼런스로 변환 될 수있다 기본 클래스 유형. 비공개 상속의 목적을 패배로

그러나 을하지 않으려 고.

+0

C++을 거의 10 년 동안 사용해 왔지만이 언어의 모서리를 여전히 발견합니다. 언어 또는 나쁜 것에 대한 좋은 코멘트인지 확실하지 않습니다. 아마 나쁜 것. 그러나 어이, 왜 지금 그만하세요. :) – AdamIerymenko

+1

사실 맨손으로 포인터, 새로운 [], 매달린 참조, 비 가상 소멸자, std :: auto_ptr (고맙게도 사용되지 않지만)와 같은 많은 까다로운 코너가 있습니다. 나는 심지어 목록에 템플릿을 추가하는 유혹을받을 것이지만 그것은 downvotes/일반적인 비웃음의 위험을 감수 할 것이다! – Bathsheba

+0

하지만 템플릿이 너무 재미 있습니다! 실제로 그들은 스위스 군대의 바주카 카테고리와 틀림없이 지나치게 사용되지는 않을지라도 언어에서 가장 좋아하는 부분입니다. – AdamIerymenko

-5

제목에 대한 자료는 answere에 달려 있습니다. 그러나 귀하의 소스 코드에서 귀하의 사례에 대한 대답은 '예'입니다.

는 answere 영향을 미치는 두 가지 요인이 있습니다

  1. 당신은 C 스타일 캐스트를 사용하는 경우, 그것은 것입니다 예, 주조 재 interpert 캐스트 변환없이 availible 경우 전화 때문입니다. 대상 유형의 포인터에 모든 유형의 포인터를 전송할 수 있습니다. 그러나 MI가있는 경우 결과는 대부분의 C++ 언어 구현에 맞지 않을 수 있습니다.

  2. memeber 함수 내에서 캐스트 (C 스타일 캐스트 없음)를 수행하면 기본 클래스가 멤버 함수 내에서 액세스 가능하기 때문에 answere가 yes가됩니다. 표현식이 기본 클래스에 액세스 할 수없는 위치에 있으면 컴파일 오류가 발생합니다.

는 C 표준 converstion ++ 표준

A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause 10) of D. 
If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. 
The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type. 

편집 2에 대한 자세한 내용이 다음과 같습니다 answere 자세한 내용을 확인하십시오.

+2

올바르지 않습니다. 다른 답변을 읽어보십시오. – Bathsheba

+4

인용 한 단락은 암시 적 * 유형 변환에 관한 것입니다. 기본 클래스에 액세스 할 수없는 경우 파생 클래스 포인터를 기본 클래스로 변환 할 수 없습니다. 파생 클래스 내부에서는 기본 클래스에 액세스 할 수 있으므로 적용되지 않습니다. 또한 C 스타일의 캐스트에 대한 특별 규칙이 있습니다. [Bathsheba] (http://stackoverflow.com/users/2380830/bathsheba)의 [answer] (http://stackoverflow.com/a/17925216/ 420683). – dyp

+0

"C 스타일 캐스팅을 사용하는 경우 변환이 불가능할 경우 캐스트가 다시 인터프리 캐스트를 호출하므로 '예'입니다. 이 경우 C 스타일의 캐스트는 인용 된 Bathsheba라는 특수 규칙을 통해 'static_cast'와 유사하게 수행됩니다 (즉, 기본 클래스를 액세스 할 수 없다는 것을 무시함). 따옴표를 넣으려면'>'또는 인용 버튼을 사용해야하며 4 칸이나 코드 버튼을 사용하면 안됩니다. – dyp

8

예, 명시 적으로 허용됩니다. Alexandrescu의 정책 기반 설계의 그의 접근에 대한 Modern C++ Design에서 광범위하게이 사용 유스 케이스가 제한 될 수 있습니다 동안

template <typename Policy> 
class foo : Policy 
{ 
    public: 
     void do_something() 
     { 
      Policy & p = *this; 
      p.do_something(); 
     } 
}; 

그래서, 거기에 몇 가지가 있습니다. 즉 좀 개인 상속의 목적에 반하는 결과가 발생할 수 있지만, 나는 그것이 가능 말하고 싶지만 특정하지 않고

+4

그러나 이것은 C 스타일의 캐스트가 아닙니다. 그것은 클래스 내부에서 개인 기지에 대한 암시 적 캐스트입니다. 내가 놓친 게 있니? – unkulunkulu

+0

암시 적 형변환은 C 형 형변환보다 더 제한적입니다. – nijansen

+0

답안의 코드 샘플에는 C 스타일의 캐스트가 없으며 기본 클래스 'Policy'에 액세스 할 수없는 코드도 없습니다. 따라서 OP가 요구 한 것과 관련이없는 것처럼 보입니다. – Quuxplusone