2010-05-29 6 views
10

나는 코드는 매우 비슷한 있습니다포인터를 추가 할 수없는 이유는 무엇입니까?

LINT_rep::Iterator::difference_type LINT_rep::Iterator::operator+(const Iterator& right)const 
{ 
    return (this + &right);//IN THIS PLACE I'M GETTING AN ERROR 
} 

LINT_rep::Iterator::difference_type LINT_rep::Iterator::operator-(const Iterator& right)const 
{//substracts one iterator from another 
    return (this - &right);//HERE EVERYTHING IS FINE 
} 

err msg: Error 1 error C2110: '+' : cannot add two pointers 

왜 난 단지 한 곳에서가 아니라 모두에서 오류를 받고 있어요?

+0

포인터 추가 란 무엇을 의미합니까? 집 주소가 3472 Main 인 경우 2와 같은 숫자를 추가하면 3474 Main이 이웃이 될 가능성이 큽니다. 하지만 두 주소를 추가하면 6946이됩니다. 그게 무슨 뜻입니까? –

답변

36

C++에서는 포인터 추가가 금지되어 있으므로 두 포인터 만 빼기 만 할 수 있습니다.

이 이유는 두 포인터를 뺀 것이 논리적으로 설명 할 수있는 결과를 제공하기 때문입니다. 두 포인터 사이의 메모리 오프셋입니다. 마찬가지로, "포인터를 위나 아래로 이동"을 의미하는 포인터에서 정수를 빼거나 더할 수 있습니다. 포인터에 포인터를 추가하는 것은 설명하기 어려운 것입니다. 최종 결과는 무엇을 나타낼까요?

주소가 다른 두 개의 주소의 합계 인 메모리에서 포인터를 명시 적으로 필요로하는 경우 두 개의 포인터를 int으로 캐스팅하고 int을 추가 한 다음 다시 포인터로 캐스트 할 수 있습니다. 그러나이 솔루션은 포인터 산술에 대한 큰 관심이 필요하며 절대 수행해서는 안됩니다.

+0

ł하지만 def에서 보는 바와 같습니다. 이 연산자 중 포인터 (반복자)가 아닌 다른 값을 반환하지만 당연히 아이디어를 얻고 있습니다. 그리고 나는 여러분에게 동의합니다. –

+0

차이점을 반환하지만, 완전한 형식을 반환하지 않으면 암시 적 캐스트가 발생합니다. 'this + & right'는 결과가'LINT_rep :: Iterator :: difference_type'에 던져지기 전에 평가되어야하고, 포인터 피연산자에 대해 연산자'+'가 정의되지 않기 때문에이 평가는 실패합니다. 이것은 합리적인 것처럼 보일지라도 실패하는 것입니다. –

+7

sizeof (int)가 sizeof (void *)가 아닐 가능성이 있기 때문에, int에 캐스트하는 것은 나쁜 생각입니다. ptr_diff_t와 같은 것을 사용하는 것이 더 나은 선택입니다. –

3

두 포인터를 뺀 것은 두 포인터 사이의 거리를 제공합니다. 두 개의 포인터를 추가 한 결과는 무엇입니까?

+0

나는 (4-2) 할 수 있다면 (4 + 2) 할 수도 있다고 생각하고 있었다. 분명히 그렇지 않습니다. –

+0

포인터의 주소의 합계로 표시된 주소에서 임의의 메모리 덩어리에 대한 포인터? ;) –

+0

@Jake하지만 더 작은 주소에서 더 큰 주소를 빼면 같은 것이 아닙니까? –

2

예를 들어, 예상 한 결과가 다른 포인터가 아니라 이동 될 오프셋에 포인터를 더하거나 뺄 것이라고 가정합니다.

C++에서는 2 개의 포인터를 빼거나 (메모리 사이의 오프셋을 가져옴) 정수 값에 포인터를 추가 할 수 있습니다. 포인터를 다른 메모리 위치로 이동하면 * sizeof (object_class)만큼 증가합니다. C++에서는 2 개의 포인터를 추가하는 것이 의미가 없지만 2 개의 메모리 위치를 추가하려면 부호없는 정수 값 (타입 변환 사용)을 추가하십시오.

+0

sizeof (x *)> sizeof (int) 인 경우 64 비트 컴파일러를 제외하고. 다른 유형의 크기와 관련하여 포인터의 크기에 대한 보장은 없습니다. – cHao

49

742 에버그린 테라스 + 1 = 743 에버그린 테라스

742 에버그린 테라스 - 1 = 741 에버그린 테라스

743 에버그린 테라스 - 741 에버그린 테라스 = 2

743 에버그린 테라스 + 741 에버그린 테라스 = ???

+0

나는 그것을 얻지 않는다. – Indrek

+2

@Indrek 네 번째 줄의 결과가 무엇을 제안합니까? 두 개의 주소를 추가하는 것은 의미가 없습니다. – fredoverflow

+1

:) 좋은 답변입니다. 정말로, 나는 그것을 의미한다. – SigTerm

2

다른 답변은 이미 설명했는데, 당신이하고있는 일이 효과가 없지만 반복자에 대해 일반적으로 operator+을 정의하려고하지만 그 시도에서 길을 잃은 것 같습니다.

포인터와 표준 임의 액세스 반복기는 모두 포인터 또는 반복기를 정수 값만큼 전진시킬 수 있습니다. iterator의 경우, operator+이 정의되며, 정수 값을 인수로 사용하여 반복자를 반환합니다.

LINT_rep::Iterator LINT_rep::Iterator::operator+(int distance) const; 

당신은 방법 등의 연산자를 정의 할 수 있지만이 방법 당신은 또한 당신이를 정의 할 필요가 교환 법칙이 성립하려면

iterator + distance 

하지만

distance + iterator 

을 쓸 수 있습니다 첫 번째 매개 변수로 거리를 사용하고 두 번째로 반복기 객체를 사용하는 friend 비 멤버 함수

friend LINT_rep::Iterator LINT_rep::Iterator::operator+(int distance, const LINT_rep::Iterator & rhs); 
0

왜 한 곳에서 오류가 발생하고 둘 모두에서 오류가 발생합니까? 당신이 두 개의 포인터를 추가하는 것이 허용되었다하더라도

이 :

return (this + &right); 

어디 가리 것이다. 생각해보십시오. 은 0x0과 같을 수 있으며 & 오른쪽은 같은 범위 (예 : 0x00000000..0x80000000 - 예 : 0x00321321)에 있습니다. 추가 할 경우 결과 주소가 두 변수 ("0x0x00321321 == 0x00444777, 이는"this "와 & 오른쪽에서 너무 멀습니다)에서 너무 멀리 떨어져 있습니다. 예약 된 메모리 (0x8xxxxxxx on win), 등등. 또한 포인터가 넘칠 수 있습니다. (아마) 금지 된 이유는 무엇일까요?

포인터에 무언가를 추가하려면 정수를 추가하십시오.

0

2 개의 포인터가 있고 그 중 하나 또는 모두가 null임을 알 수 있습니다. null가 아닌 것을 돌려 주거나, 둘 다 null 인 경우 null을 리턴하려고합니다. 가장 쉬운 방법은 그들을 합산/xor하는 것입니다. 포인터를 합산하는 프로퍼티 케이스입니다.

+0

표준은 널 포인터가 모두 0이어야 함을 보장하지 않습니다. –

+0

4.10/1 "널 포인터 상수는 0 또는 std :: nullptr_t 유형의 prvalue로 평가되는 정수 유형의 정수 상수 표현식 (5.19) prvalue입니다." 값이 0 인 정수 유형의 비트가 모두 0 인 시스템에서 작업하는 한,이 비트는 0을 유지합니다. –

관련 문제