class A
{
public:
int i;
int j;
};
class B : public A
{
public:
int k;
};
main()
{
A *a = new B;
}
슬라이싱 데이터에 액세스 할 수 있습니까?개체 조각에 액세스하는 방법?
class A
{
public:
int i;
int j;
};
class B : public A
{
public:
int k;
};
main()
{
A *a = new B;
}
슬라이싱 데이터에 액세스 할 수 있습니까?개체 조각에 액세스하는 방법?
슬라이스는 다음과 같습니다
struct B {
virtual ~B() { }
};
struct D : public B {
int a, b;
};
int main()
{
D der;
B bas(der); // der is sliced!
}
는 B bas
객체가 정보가 비록 D der
의 추가 정보를 볼 수있는 방법이 없습니다. 우리는 추가 정보가 "분리되어"있다고 말합니다. bas
은 alignment 목적으로 표준이 D
개체를 (거의) 임의의 방식으로 메모리에 저장할 수 있기 때문에이 개체에 액세스 할 수 없습니다. der
에 대한 유일한 보증은 첫 번째 데이터 멤버의 주소가 객체의 주소와 동일하다는 것입니다.
답변은 포인터를 다운 캐스팅하는 것입니다.
static_cast<B*>(a)->k = 10;
전제는 당신이 실제로 가상 함수의 부족과의 vtable에 대한 방법이 없습니다, 때문에 코드에서이 시점에서 a
항상 B
의 인스턴스를 참조해야 알고 있다는 것입니다 캐스팅이 유효한지, 런타임에 테스트 할 언어. 모든 컴파일러가 알고 들어, A 형의 객체에 대한 포인터를 가지고 있기 때문에 기술적으로는 아무 것도 아직 슬라이스되지
, 당신은 그렇지 않으면 액세스 할 수 없습니다, 이것은 단순히 알고 있어야합니다 경우입니다 보다 나은.
IMO, 당신은 단지 데이터 만 잡아, 당신은 일반적으로 모든 기본 클래스에 대한 포인터 덤비는하지 않아야가 클래스에 데이터 필드를 추가 할 상속을 사용하는 경우.
코드의 일부만 표시하고 거기에 가상 함수가있는 경우 캐스팅이 유효한지 확인할 수 있기 때문에 dynamic_cast
을 대신 사용하십시오.
여기에 개체 조각이 없습니다. 더 자세하게 얘기해 주 시겠어요? * 객체 분할에 액세스하는 것이 무엇을 의미합니까? – Naveen
이것에 관한 좋은 토론은 http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c를 참조하십시오. –
@Naveen :하지만 프로그래머가 계속 추적하고 기억하지 않으면 그것은 B라는 것입니다.'* a'도 B 부분을 포함하고 있다는 것을 알 수있는 방법이 없기 때문에 슬라이스만큼 좋습니다. – UncleBens