简体   繁体   中英

Correct Implementation of Vector 3 in c++

I have just begun dabbling in c++. Is this the correct implementation of a vector 3? I don't want to leak any memory, or do anything that is just bad form in c++. Are my operator overload signatures correct?

class Vector
{
private:
    double _x;
    double _y;
    double _z;
    double LengthSquared();
    friend std::ostream& operator<<(std::ostream& stream, const Vector& vector);
public:
    Vector();
    Vector(double x, double y, double z);
    ~Vector();
    Vector(Vector& other);  
    double GetX() const;
    double GetY() const;
    double GetZ() const;
    double Length();    
    Vector& Normalize();
    double DotProduct(const Vector& vector) const;
    Vector CrossProduct(const Vector& vector);
    bool operator==(const Vector& vector) const;
    bool operator!=(const Vector& other) const;
    Vector& operator+=(const Vector& vector);
    Vector operator+(const Vector& vector) const;
    Vector& operator-=(const Vector& vector);
    Vector operator-(const Vector& vector) const;
    Vector& operator*=(double val);
    double operator*(const Vector& vector) const;
    Vector operator*(double val) const; 
};

Vector::Vector() : _x(0.0), _y(0.0), _z(0.0)
{
}

Vector::Vector(double x, double y, double z) : _x(x), _y(y), _z(z)
{
}

Vector::~Vector()
{
}

Vector::Vector(Vector& other) : _x(other._x), _y(other._y), _z(other._z)
{
}

double Vector::GetX() const
{
    return _x;
}

double Vector::GetY() const
{
    return _y;
}

double Vector::GetZ() const
{
    return _z;
}

double Vector::Length()
{
    return sqrt(LengthSquared());
}

double Vector::LengthSquared()
{
    return (_x * _x + _y * _y + _z * _z);
}

Vector& Vector::Normalize()
{
    double length = Length();

    if(length >0)
    {
        _x = _x / length;
        _y = _y / length;
        _z = _z / length;
    }
    else
    {
        _x = 0;
        _y = 0;
        _z = 0;
    }

    return *this;
}

double Vector::DotProduct(const Vector& vector) const
{
    return _x * vector.GetX() + _y * vector.GetY() + _z * vector.GetZ();        
}

Vector Vector::CrossProduct(const Vector& vector)
{
    double nx = _y * vector.GetZ() - _z * vector.GetY();
    double ny = _z * vector.GetX() - _x * vector.GetZ();
    double nz = _x * vector.GetY() - _y * vector.GetX();

    return Vector(nx, ny, nz);
}

bool Vector::operator==(const Vector& vector) const
{
    if(this == &vector)
        return true;

    if((_x == vector.GetX()) && (_y == vector.GetY()) && (_z == vector.GetZ()))
        return true;

    return false;
}

bool Vector::operator!=(const Vector& vector) const
{
    return !(*this == vector);  
}

Vector& Vector::operator+=(const Vector& vector)
{   
    _x += vector.GetX();
    _y += vector.GetY();
    _z += vector.GetZ();

    return *this;
}

Vector Vector::operator+(const Vector& vector) const
{
    return Vector(_x, _y, _z) += vector;
}

Vector& Vector::operator-=(const Vector& vector)
{   
    _x -= vector.GetX();
    _y -= vector.GetY();
    _z -= vector.GetZ();    

    return *this;
}

Vector Vector::operator-(const Vector& vector) const
{
    return Vector(_x, _y, _z) -= vector;
}

Vector& Vector::operator*=(double val)
{   
    _x *= val;
    _y *= val;
    _z *= val;  

    return *this;
}

double Vector::operator*(const Vector& vector) const
{   
    return this->DotProduct(vector);
}

Vector Vector::operator*(double val) const
{
    return Vector(_x, _y, _z) *= val;
}

std::ostream& operator<<(std::ostream& stream, const Vector& vector)
{
    return stream << "x: " << vector._x << ", y: " << vector._y << ", z: " << vector._z;
}
  • I would avoid the leading underscores on your attribute names. These particular names are legal but many led by _ are not.
  • Length and LengthSquared should be const .
  • The compiler generated copy constructor and destructor will do the right thing - no need to write them yourself and risk a copy-paste error.
  • Consider making DotProduct and CrossProduct non-member, non-friend "algorithm" functions. Also consider this for the non-mutating operators (which can then be written in the canonical form T operator+(T left, const T& right) { return left += right; }
  • Strongly consider not providing an operator* at all as it's not intuitive if it means scalar, dot, or cross product. Use named methods instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM