C ++에서 업 캐스팅은 언제 불법입니까?
나는 특히 C ++에서 업 캐스팅과 다운 캐스팅의 일반적인 차이점을 이해하고 있다고 확신합니다. 기본 클래스 포인터를 파생 클래스 포인터로 캐스팅하면 가리키는 기본 클래스 개체에 파생 클래스의 모든 멤버가 있다고 가정하므로 항상 다운 캐스트 할 수는 없음을 이해합니다.
학기 초에 교수님 께서 수업 시간에 C ++로 업 캐스트하는 것도 불법이라고 말씀 하셨는데, 메모에서 그 이유를 놓친 것 같고 언제 이런 일이 발생했는지 기억이 나지 않습니다.
C ++에서 업 캐스트하는 것은 언제 불법입니까?
"불법"이란 잘못된 형식을 의미하는 경우 기본 클래스에 액세스 할 수 없거나 모호한 경우 불법입니다.
예를 들어 기본 클래스가 비공개 인 경우 액세스 할 수 없습니다.
class A {}; class B : A {}; ... B b; A *pa = &b; // ERROR: base class is inaccessible
C ++ 11에서도 C 스타일 캐스트는 액세스 보호를 "돌파"하고 공식적으로 올바른 업 캐스트를 수행 할 수 있습니다.
A *pa = (A *) &b; // OK, not a `reinterpret_cast`, but a valid upcast
물론 이러한 사용은 피해야합니다.
소스 유형에 대상 유형의 여러 기본 하위 객체가 포함되어있는 경우 (다중 상속을 통해) 모호합니다.
class A {}; class B : public A {}; class C : public A {}; class D : public B, public C {}; D d; A *pa = &d; // ERROR: base class is ambiguous
이러한 경우 업 캐스트는 중간 업 캐스트가있는 원하는 업 캐스트 경로를베이스가 더 이상 모호하지 않은 지점까지 명시 적으로 "보행"하여 수행 할 수 있습니다.
B* pb = &d; A* pa = pb; // OK: points to 'D::B::A' subobject
기본 클래스가 모호한 경우 (다른 경로를 통해 두 번 이상 상 속됨) 한 단계로 업 캐스트를 수행 할 수 없습니다.
기본 클래스에 액세스 할 수없는 경우 업 캐스트하는 유일한 방법은 C 스타일 캐스트를 사용하는 것입니다. 이것은 그 캐스트의 특별한 경우이며 일을 할 수있는 유일한 사람입니다. 기본적으로는 static_cast
접근성에 의해 제한되지 않는 것처럼 작동 합니다.
Standardese.
C ++ 11 §5.4 / 4 :
” … [a C cast]
static_cast
에서 다음 상황에서 a 를 수행 하면 기본 클래스에 액세스 할 수없는 경우에도 변환이 유효합니다.
- 파생 클래스 유형의 개체에 대한 포인터 또는 파생 클래스 유형의 lvalue 또는 rvalue는 각각 명확한 기본 클래스 유형에 대한 포인터 또는 참조로 명시 적으로 변환 될 수 있습니다.
- 파생 클래스 형식의 멤버에 대한 포인터는 모호하지 않은 비가 상 기본 클래스 형식의 멤버에 대한 포인터로 명시 적으로 변환 될 수 있습니다.
- 모호하지 않은 비가 상 기본 클래스 유형의 객체에 대한 포인터, 모호하지 않은 비가 상 기본 클래스 유형의 glvalue 또는 모호하지 않은 비가 상 기본 클래스 유형의 멤버에 대한 포인터는 명시 적으로 포인터로 변환 될 수 있습니다. 참조 또는 파생 클래스 형식의 멤버에 대한 포인터입니다.
모호성의 예 :
struct Base {};
struct M1: Base {};
struct M2: Base {};
struct Derived: M1, M2 {};
auto main() -> int
{
Derived d;
//static_cast<Base&>( d ); //! Ambiguous
static_cast<Base&>( static_cast<M2&>( d ) ); // OK
}
캐스트에서 (일반적으로) 주소 조정이있는 액세스 할 수없는베이스의 예 :
struct Base { int value; Base( int x ): value( x ) {} };
class Derived
: private Base
{
public:
virtual ~Derived() {} // Just to involve an address adjustment.
Derived(): Base( 42 ) {}
};
#include <iostream>
using namespace std;
auto main() -> int
{
Derived d;
Base& b = (Base&) d;
cout << "Derived at " << &d << ", base at " << &b << endl;
cout << b.value << endl;
};
업 캐스팅이 C ++에서 잘못 구성되는 두 가지 경우가 있습니다 (컴파일시 진단 됨).
문제의 기본 클래스에 액세스 할 수 없습니다 .
class base {}; class derived : base {}; int main() { derived x; base& y = x; // invalid because not accessible. // Solution: C-style cast (as static_cast without access-check) base& y1 = (base&)x; }
문제의 기본 클래스 하위 개체는 명확하지 않습니다 .
class base {}; struct A1 : base {}; struct A2 : base {}; struct derived : A1, A2 {}; int main() { derived x; base& y = x; // invalid because ambiguous. // Solution 1, scope resolution: base& y1 = static_cast<A1::base&>(x); base& y2 = static_cast<A2::base&>(x); // Solution 2, intermediate unambiguous steps: A1& a1 = x; A2& a2 = x; base& ya1 = a1; base& ya2 = a2; }
참조 URL : https://stackoverflow.com/questions/26982648/when-is-upcasting-illegal-in-c
'program tip' 카테고리의 다른 글
기술적으로 가변 함수는 어떻게 작동합니까? (0) | 2020.12.31 |
---|---|
Scala repl에서 오류 발생 (0) | 2020.12.31 |
새로운 RazorEngine API를 사용한 템플릿 (0) | 2020.12.31 |
DateTime 'Z'형식 지정자는 어디에 있습니까? (0) | 2020.12.31 |
Liskov 대체 원칙-재정의 / 가상 방법 없음? (0) | 2020.12.31 |