4

カスタムC++クラスを使用して3D位置を管理する際に問題を見つけるのに助けが必要です。カスタムC++クラスのバグ

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

どこnodo [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]; 

をコンパイラは言う:

メンバ関数0123でプント*「と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; (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]); 

もう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つのパラメータを持つクラス外のoperator +を宣言できます。しかし、それはオブジェクトを返す必要があります。ですから、+演算子はオペランドと同じ型を返しません。私はこれを行うことをお勧めしません。 –

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+をオーバーロードパラメータの少なくとも1つは、する必要があるため:

は、基本的にはこのような何かをしたいですとなります。プリミティブ型の演算子オーバーロードはなく、ポインタもそのようにカウントされます。

+0

同じですが、どこでも参照しているのは醜いですが、それをよりシンプルに見せるためのヒントはありますか? –

+0

あなたはelementoFronteraベクトルにPuntoオブジェクトのポインタの代わりにPuntoオブジェクトを格納できますか?次に、 "+"は期待どおりに機能します... – sth

+0

考え方は、Puntoオブジェクトが保存されている他の場所を指し示すことです。 –

関連する問題