4

커스텀 C++ 클래스를 사용하여 3D 위치를 관리 할 때 도움이 필요합니다.커스텀 C++ 클래스의 버그

p = fem->elementoFrontera[i]->nodo[0] - fem->elementoFrontera[i]->nodo[1]; 

곳은 있소 [i]를하는 푼토 *이며, 잘 컴파일하지만 내가하려고하면 여기에 내가 같이 여기를 사용하고

Punto operator+(Punto p){ 
    return Punto(this->x + p.x, this->y + p.y, this->z + p.z); 
    } 

    Punto operator+(Punto *p){ 
    return Punto(this->x + p->x, this->y + p->y, this->z + p->z); 
    } 

    Punto operator-(Punto p){ 
    return Punto(this->x - p.x, this->y - p.y, this->z - p.z); 
    } 

    Punto operator-(Punto *p){ 
    return Punto(this->x - p->x, this->y - p->y, this->z - p->z); 
    } 

    Punto *operator=(Punto p){ 
    this->x = p.x; 
    this->y = p.y; 
    this->z = p.z; 
    return this; 
    } 

    Punto *operator=(Punto *p){ 
    this->x = p->x; 
    this->y = p->y; 
    this->z = p->z; 
    return this; 
    } 

클래스에서 해당 코드는 할 :

p = fem->elementoFrontera[i]->nodo[0] + fem->elementoFrontera[i]->nodo[1]; 

을 컴파일러는 말한다 :

멤버 함수년푼토 * '와 Punto*' to binary 연산자 +'

+0

생성자와 .h 코드를 얻을 수 있습니까? –

+0

Punto (double _x, double _y, double _z) { x = _x; y = _y; z = _z; (Punto * v) { x = v-> x; y = v-> y; z = v-> z; } Punto (const Punto & v) { x = v.x; y = v.y; z = v.z; } –

+0

이와 같은 혼란은 연산자 오버로드를 피하는 훌륭한 사례입니다 ... – ojrac

답변

5

는 C/C++에서 포인터를 빼기하지만, 포인터를 추가 할 수 있기 때문에 첫 번째는 잘 컴파일합니다. 그러나 어떤 경우 든 그것은 당신이 필요로하는 것을하지 않습니다. 당신의 과부하 된 운영자를 사용하지 않습니다. 연산자는 클래스에 정의되어 있으므로 포인터가 아닌 클래스 인스턴스에서 작업해야합니다. 따라서 다음과 같이 변경하십시오.

Punto p = *(fem->elementoFrontera[i]->nodo[0]) + *(fem->elementoFrontera[i]->nodo[1]); 

또 다른 사항 - 연산자 정의에서 값이 아닌 클래스 참조를 사용해야합니다. 예 :

Punto& operator+(const Punto& p) { 

EDIT.

const Punto& NodoRef(int i, int j) { 
    return *(fem->elementoFronteria[i]->Nodo[j]); 
} 

을 및 NodoRef 외부 사용자의 FEM 클래스에 정의 될 수 있거나 깨끗한

p = NodoRef(i,0) + NodoRef(i,1); 

으로 다음 코드가된다 : 코드를 단순화하기 위해이 같은 접근 기능을 만들 수 있습니다. NodoRef를 사용하는 범위에서 오브젝트 펨토시가 살아 있는지 확인하십시오.

+0

어쨌든 더 예뻐 보이게 할 수 있습니까? 내 말은, 각각의 작업에 코드를 파기하는 것은보기 흉한 일이라고 생각하지 않습니까? –

+0

맛이 좋습니다. 나는 명백한 코드와 숨겨진 마술을 선호하지 않습니다. 포인터가 있으면 어떤 조작을 적용하기 전에 역 참조 할 필요가 있습니다. –

+0

기술적으로 Punto에 대한 포인터에 정의 된 2 개의 매개 변수를 사용하여 out-of-class 연산자 +를 선언 할 수 있습니다. 그러나 그것은 객체를 반환해야합니다. 그래서, 추악합니다 : + 연산자는 피연산자와 같은 타입을 반환하지 않습니다. 나는 이것을하는 것을 추천하지 않을 것이다. –

0

첫 번째 버전은 "-"이 일반적인 포인터 연산을 수행하기 때문에 작동하며 오버로드 된 연산자를 사용하지 않습니다. "+"은 일반 포인터에 정의되어 있지 않으므로 오류가 발생합니다. 그 첫 번째 포인터 역 참조, 오버로드 된 버전을 사용하게하려면, 당신은 오버로드의 두 가지 유형이 있기 때문에 또한 작동합니다 모두 포인터를 역 참조

p = *fem->elementoFrontera[i]->nodo[0] - fem->elementoFrontera[i]->nodo[1]; 

있지만,이 경우에는 const를 참조를 사용하는 운영자의 정의를 변경해야합니다 :

Punto operator+(const Punto &p){ 
    ... 
} 

이렇게하면 "+"을 사용할 때마다 개체가 복사되지 않습니다.

const Punto operator+(Punto *left, Punto *right); // not allowed 

하지만, 무료로 기능이 포인터를 받아 작동하지 않는 적절한 방법으로 추가 operator+ 과부하 매개 변수 중 하나가 필요하기 때문에 :

은 기본적으로 당신이 그런 짓을 할 enum or class type이어야합니다. 원시 타입에는 연산자 오버로딩이없고, 포인터는 그만큼 중요합니다.

+0

같은 생각으로 도처에서 추론하는 것은 추한 것입니다. –

+0

Punto 객체를 포인터 대신 자신의 요소 인 Frontera 벡터에 저장할 수 있습니까? 그런 다음 "+"는 예상대로 작동합니다 ... – sth

+0

아이디어는 Punto 객체가 저장된 다른 위치를 가리키는 것입니다. –