문제

객체 데이터 멤버의 위치 오프셋을 다음보다 더 나은 방법이 있습니까?

class object
{
  int a;
  char b;
  int c;
};

object * o = new object();
int offset = (unsigned char *)&(object->c) - (unsigned char *)o;
delete o;
도움이 되었습니까?

해결책

이 경우 수업은 포드이므로 offsetof 매크로 <cstddef>.

실제로 대부분의 구현에서 대부분의 클래스에서 오프셋이 일반적으로 사용하는 것과 동일한 트릭을 사용할 수 있습니다.

int offset = &(((object *)0)->c) - (object *)0;

실제로 객체를 만들 필요는 없지만 컴파일러 경고와 싸워야 할 수도 있지만 작동하는 것이 보장되지 않기 때문입니다.

또한 귀하의 클래스가 여러 상속 재산을 가지고 있다면 적어도 하나의 기반을 제외한 모든 것을 위해서는 (void*)(base*)some_object != (void*)(derived*)some_object. 따라서 오프셋을 적용하는 내용을 조심해야합니다. 필드를 실제로 정의하는 클래스에 대한 포인터에 대해 계산하고 적용하는 한 (즉, 파생 클래스 포인터에서 기본 클래스 필드의 오프셋을 해결하려고 시도하지 마십시오). 좋아. 객체 레이아웃에 대한 보장은 없지만 대부분의 구현은 명백한 방법으로 수행합니다.

기술적으로 POD가 아닌 클래스의 경우 기본 포인터에서 필드의 "오프셋"에 대해 이야기하는 것은 의미가 없습니다. 포인터 간의 차이가 해당 클래스의 모든 객체에 대해 동일 할 필요는 없습니다.

다른 팁

실제로 객체를 만들 필요가 없습니다.

(size_t)&(((object*)0)->c)

즉, 주소 0의 객체에있는 멤버의 주소는 해당 멤버의 오프셋으로 오프셋입니다.

물론 회원에 대한 액세스가 필요하므로 struct 또는 추가하십시오 public: 액세스 수정 자.

이것이 방법입니다 offsetof 적어도 대부분의 컴파일러에 대해 구현됩니다.

포인터보다는.
회원에게 포인터를 사용할 수 있습니다.

class X;
typedef int X::*    PtrToMemberInt;  // Declare a pointer to member.

class X
{
    int a;
    char b;
    float c;

    public:
    static PtrToMemberInt   getAPtr()
    {
        return &X::a;
    }

    int d;
};

int main()
{
    // For private members you need to use a public method to get the address.
    PtrToMemberInt aPtr = X::getAPtr();

    // For public members you can take the address directly;
    PtrToMemberInt dPtr = &X::d;


    // Use the pointer like this:
    X   a;
    a.*aPtr = 5;
    a.*dPtr = 6;
}

Stroustrup의 "C ++의 디자인 및 진화"에 명시된대로 Martins 답변에 추가하기 위해 : 섹션 [13.11]) :

데이터 구성원에 대한 포인터는 구현에서 C ++ 클래스의 레이아웃을 표현하는 유용한 방법을 입증했다 [Hübel, 1992

Sandeep은 원래 종이를 변환하고 사용할 수 있도록 친절했습니다. http://sandeep.files.wordpress.com/2008/07/ps.pdf

구현에 설명 된 구현은 Predated C ++ RTTI를 설명했지만 때때로 포인터 투 관련 제품을 사용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top