4

Мне нужна помощь в поиске проблемы с использованием настраиваемого класса C++ для управления 3D-позициями. Вот соответствующий код из классаОшибка в пользовательском классе C++

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 *, и он компилируется нормально, но когда я пытаюсь делать:

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

компилятор говорит:

в функции члена void mdTOT::pintarElementosFrontera()': error: invalid operands of types Punto * «и Punto*' to binary оператор +»

+0

Можем ли мы получить конструктор и код .h? –

+0

Punto (double _x, double _y, double _z) { x = _x; y = _y; z = _z; } Punto (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]); 
} 

, а затем ваш код становится таким же чистым, как

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

NodoRef может быть определен в классе FEM, или за ее пределами. Просто убедитесь, что объект fem жив в области, где вы используете NodoRef.

+0

В любом случае, чтобы он выглядел красивее? Я имею в виду, что это безобразно быть отсроченным кодом на каждой операции, не так ли? –

+0

Это вопрос вкуса. Я предпочитаю явный код и скрытую магию. Если у меня есть указатель, я знаю, что нужно разыгрывать его перед применением каких-либо операций. –

+0

Технически вы можете объявить внеклассный оператор + с двумя параметрами, определенными на указателях на Punto. Но он должен вернуть объект. Итак, это уродливо: оператор + не возвращает тот же тип, что и операнды. Я бы не рекомендовал это делать. –

0

Первая версия работает, потому что «-» выполняет обычную арифметику указателя в этом случае, она не использует ни одного из ваших перегруженных операторов. «+» не определен в обычных указателях, поэтому вы получаете сообщение об ошибке. Для того, чтобы сделать его использовать перегруженную версию, разыменовать первый указатель:

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

Разыменования оба указателя должен также работать, так как у вас есть оба типа перегрузок, но вы должны изменить определение оператора использовать константные ссылки в этом случае:

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

Таким образом, объекты не копируются каждый раз, когда вы используете «+».

В основном вы хотите сделать что-то вроде этого:

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

Но перегружать свободную функцию operator+, которая принимает два указателя и добавляет их соответствующим образом не работает, потому что по крайней мере один из параметров должен от enum or class type. Не существует перегрузки оператора для примитивных типов, а указатели считаются таковыми.

+0

То же самое здесь, уродливо быть отсрочкой повсюду, любые намеки на то, чтобы сделать его проще? –

+0

Не могли бы вы просто сохранить объекты Punto вместо указателей на них в вашем векторе elementoFrontera? Затем «+» будет работать так, как ожидалось ... – sth

+0

Идея состоит в том, чтобы указать на другое место, где сохраняются объекты Punto. –

Смежные вопросы