2015-01-07 2 views
0

C++의 "this"포인터 (있는 경우)에 대해 포인터 연산을 수행하기위한 합법적 인 및/또는 흥미로운 용도는 무엇입니까?"this"포인터에 대한 포인터 연산

SE를이 질문의 길이만큼 기쁘게 만들려면 관련 코드를 포함시켜야합니다.

class Foo 
{ 
public: 
    Foo(bool terminate = false) 
     : _data(terminate ? -1 : 0) 
    {} 

    void Bar(void) 
    { 
     if (_data >= 0) 
     { 
      _data++; 
      this[1].Bar(); 
     } 
    } 

private: 
    int _data; 
}; 

void main() 
{ 
    std::vector<Foo> vec; 
    vec.push_back(Foo()); 
    vec.push_back(Foo()); 
    vec.push_back(Foo()); 
    vec.push_back(Foo()); 
    vec.push_back(Foo(true)); 

    vec[2].Bar(); 
} 
+6

개체가 연속 배열의 멤버임을 인식해서는 안되기 때문에이 작업을 수행 할 정당한 이유는 없습니다. 그리고 당신의 코드는 무한 재귀 적입니다. –

+5

나는이 질문에 길이가 불만의 근원이 될 것이라고 생각하지 않는다. –

+1

스택 오버플로는 "프로그래머에게 아무것도 묻지"않습니다. 여기는 규칙이 아닙니다. – Yakk

답변

4

짧은 대답 :하지 마십시오.

당연히 모든 종류의 흑 마법을 수행합니다. 표시 한 것과 같은 이전 또는 다음 배열 요소에 액세스하거나, 포인터 오프셋을 통해 기본 클래스의 전용 멤버에 액세스하거나, 절대로 이동하지 않는 한 해당 메모리 위치에서 객체의 '고유 한'ID를 가져옵니다. 그러나이 모든 것들은 어느 시점에 역효과를 낼 가능성이 매우 높습니다. 그리고 내가 생각할 수있는 모든 것에 대해 안전한 해결책이 있습니다.

제가 생각할 수있는 합법적 인 용도 중 하나는 정렬 검사입니다. 16 바이트 정렬이 필요한 float4 클래스가 있다고 가정하면 생성자에 (((uintptr_t)(const void *)(this)) % 16 == 0)을 보장하는 어설 션을 넣을 수 있습니다.

0

그것은 합법적이지만 의견이 당신에게 말했듯이, 그것은 끔찍한 스타일입니다.

툴체인 개발자가 적합성 테스트를 작성하는 경우를 제외하고는이 작업을 수행하지 마십시오.