2011-12-15 108 views
2

編譯器在嘗試減去兩個Point3D對象時給了我一個錯誤。我得到這個錯誤:操作符函數的操作符重載時出現問題

Invalid operands to binary expression ('Point3D' and 'Point3D') 

這是我在我的Vector3D.h:

#include "Point3D.h" 
using namespace std; 
class Vector3D 
{ 
    friend const Point3D operator+(const Point3D& a, const Vector3D& b); 
    friend const Vector3D operator-(const Point3D& a, const Point3D& b); 

public: 

    Vector3D() {} 
    Vector3D(float x, float y, float z); 
    Vector3D(Point3D const& originPoint, float theta, float distance); 
    float getX() const {return x;} 
    float getY() const {return y;} 
    float getZ() const {return z;} 
    static Vector3D minus(Point3D const& destination, Point3D const& origin); 
    Vector3D operator-(Vector3D const& other) const; 
    float dot(Vector3D const& other) const; 
    static float angleBetweenTwoVectorsZeroToPi(Vector3D const& a, Vector3D const& b); 
    static float angleBetweenTwoVectorsZeroToTwoPi(Vector3D const& a, Vector3D const& b); 
    Vector3D normalize() const; 
    float length() const; 
    //const float * const getArray() const {return &x;} 
    Vector3D multiply(float scalar) const; 
    bool operator==(Vector3D const& v) const; 
    float operator[] (int i) const; 
private: 
    float x; 
    float y; 
    float z; 
}; 

的Vector3D.cpp文件定義了二進制運算符:

#include "Vector3D.h" 
#include "Math3D.h" 
#include <math.h> 
#include "MathConstants.h" 

Vector3D::Vector3D(float x, float y, float z): 
x(x), y(y), z(z) 
{} 

Vector3D::Vector3D(Point3D const& originPoint, float theta, float distance) 
{ 
    Point3D endPoint = Math3D::calcaultePoint3D(originPoint, theta, distance); 
    Vector3D result = minus(endPoint, originPoint); 
    this->x = result.x; 
    this->y = result.y; 
    this->z = result.z; 

} 

Vector3D Vector3D::minus(Point3D const& destination, Point3D const& origin) 
{ 
    return Vector3D(destination.getX() - origin.getX(), 
        destination.getY() - origin.getY(), 
        destination.getZ() - origin.getZ()); 
} 

Vector3D Vector3D::operator-(Vector3D const& other) const { 
    return Vector3D(x-other.x, y-other.y, z-other.z); 
} 

float Vector3D::dot(const Vector3D &other) const 
{ 
    return x * other.x + y * other.y + z * other.z; 
} 



float Vector3D::length() const 
{ 
    return sqrtf(dot(*this)); 
} 

Vector3D Vector3D::normalize() const 
{ 
    float len = length(); 
    return Vector3D(getX()/len, getY()/len, getZ()/len); 
} 

Vector3D Vector3D::multiply(float scalar) const { 
    return Vector3D(x * scalar, y * scalar, z * scalar); 
} 

float Vector3D::angleBetweenTwoVectorsZeroToPi(const Vector3D &a, const Vector3D &b) 
{ 
    /* 
    * The result is between 0 and PI 
    */ 
    Vector3D unitA = a.normalize(); 
    Vector3D unitB = b.normalize(); 
    return acos(unitA.dot(unitB)); 

} 

bool Vector3D::operator==(const Vector3D &v) const { 
    return (x == v.x) && (y == v.y) && (z == v.z); 
} 

float Vector3D::operator[](int i) const { 
    return (&x)[i]; 
} 

float Vector3D::angleBetweenTwoVectorsZeroToTwoPi(const Vector3D &a, const Vector3D &b) 
{ 
    /* 
    * The result is between 0 and 2PI 
    * 
    * "Assuming a = [x1,y1] and b = [x2,y2] are two vectors with their bases at the 
    * origin, the non-negative angle between them measured counterclockwise 
    * from a to b is given by 
    * 
    * angle = mod(atan2(x1*y2-x2*y1,x1*x2+y1*y2),2*pi); 
    * 
    * As you can see, this bears a close relationship to the three-dimensional 
    * formula I wrote last July 10. The quantities, x1*y2-x2*y1 and x1*x2+y1*y2 
    * are, respectively, the sine and cosine of the counterclockwise angle from 
    * vector a to vector b, multiplied by the product of their norms - that is, their 
    * cross product and the dot product restricted to two dimensions. The 'atan2' 
    * function then gives the angle between them ranging from -pi to +pi, and the 
    * 'mod' operation changes this so as to range from 0 to 2*pi, as you requested." 
    * 
    * Roger Stafford 
    * http://www.mathworks.com/matlabcentral/newsreader/view_thread/151925 
    */ 
    float resultNegPiToPosPi = atan2f(a.x*b.y-b.x*a.y, a.x*b.x+a.y*b.y); 
    if (resultNegPiToPosPi < 0.0f) 
    { 
     resultNegPiToPosPi = resultNegPiToPosPi + 2*MathConstants::PI; 
    } 
    return resultNegPiToPosPi; 
} 


const Point3D operator+(const Point3D& a, const Vector3D& b) {return Point3D(a.getX()+b.getX(), a.getY()+b.getY(), a.getZ()+b.getZ());} 


const Vector3D operator-(const Point3D& a, const Point3D& b) {return Vector3D(a.getX()-b.getX(), a.getY()-b.getY(), a.getZ()-b.getZ());} 

這是我嘗試從另一個Point3D中減去:

void AnimationService::handlePlayerMovement(double lastTime, double currentTime, Vector3D vector) { 

    Point3D a; 
    Point3D b; 
    Vector3D result = a - b; // this is the problem line 
} 

奇怪的部分是,二進制operator+確實有效,但由於某種原因,operator-給了我錯誤。誰能告訴我我做錯了什麼?

+0

爲什麼你的操作符返回一個const對象?嘗試刪除它。 – Dani 2011-12-15 03:22:30

+0

你可以發佈錯誤發生的代碼嗎?還有你在哪裏定義兩個操作符? – Xeo 2011-12-15 03:39:50

回答

3

當一個函數的聲明僅是friend聲明,我相信功能只發現當其論據之一是其宣佈的類型時。由於operator +採用Vector3D,因此編譯器在查找它時查找Vector3D內部。由於操作員只需要使用Point3D,因此編譯器在Point3D中查找而不在Vector3D中查找,因此找不到操作員。

正如Xeo所說,將函數聲明移到類之外,它應該可以工作。