2010-05-07 2 views
-1
class A 
{ 
public: 
int i; 
int j; 

}; 

class B : public A 
{ 
public: 
int k; 

}; 

main() 
{ 
    A *a = new B; 

} 

슬라이싱 데이터에 액세스 할 수 있습니까?개체 조각에 액세스하는 방법?

+4

여기에 개체 조각이 없습니다. 더 자세하게 얘기해 주 시겠어요? * 객체 분할에 액세스하는 것이 무엇을 의미합니까? – Naveen

+1

이것에 관한 좋은 토론은 http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c를 참조하십시오. –

+0

@Naveen :하지만 프로그래머가 계속 추적하고 기억하지 않으면 그것은 B라는 것입니다.'* a'도 B 부분을 포함하고 있다는 것을 알 수있는 방법이 없기 때문에 슬라이스만큼 좋습니다. – UncleBens

답변

1

슬라이스는 다음과 같습니다

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의 추가 정보를 볼 수있는 방법이 없습니다. 우리는 추가 정보가 "분리되어"있다고 말합니다. basalignment 목적으로 표준이 D 개체를 (거의) 임의의 방식으로 메모리에 저장할 수 있기 때문에이 개체에 액세스 할 수 없습니다. der에 대한 유일한 보증은 첫 번째 데이터 멤버의 주소가 객체의 주소와 동일하다는 것입니다.

0

답변은 포인터를 다운 캐스팅하는 것입니다.

static_cast<B*>(a)->k = 10; 

전제는 당신이 실제로 가상 함수의 부족과의 vtable에 대한 방법이 없습니다, 때문에 코드에서이 시점에서 a 항상 B의 인스턴스를 참조해야 알고 있다는 것입니다 캐스팅이 유효한지, 런타임에 테스트 할 언어. 모든 컴파일러가 알고 들어, A 형의 객체에 대한 포인터를 가지고 있기 때문에 기술적으로는 아무 것도 아직 슬라이스되지


, 당신은 그렇지 않으면 액세스 할 수 없습니다, 이것은 단순히 알고 있어야합니다 경우입니다 보다 나은.


IMO, 당신은 단지 데이터 만 잡아, 당신은 일반적으로 모든 기본 클래스에 대한 포인터 덤비는하지 않아야가 클래스에 데이터 필드를 추가 할 상속을 사용하는 경우.

코드의 일부만 표시하고 거기에 가상 함수가있는 경우 캐스팅이 유효한지 확인할 수 있기 때문에 dynamic_cast을 대신 사용하십시오.

관련 문제