Home > Enterprise >  Vector Scalar multiplication using operator function
Vector Scalar multiplication using operator function

Time:03-01

I got a Vector, need to do Scalar multiplication using operator function, but it keeps fail.

I must use operator function to run this, can't use other way.

it is not multiplication the Vector, What did I do wrong?

and what shout I do?

#include <iostream>
#include <math.h>
#include <iomanip>

using namespace std;

class Vector3D {
public:
    Vector3D(void) : X(0), Y(0), Z(0) {};                
    Vector3D(float X, float Y, float Z) : X(X), Y(Y), Z(Z) {} 
    Vector3D(const Vector3D &A) : X(A.X), Y(A.Y), Z(A.Z) {}  
     

     void operator =(const Vector3D &A)
    {               // A is a const (read-only) reference to V
        X = A.X;    // this->X = A.X;  // r is this
        Y = A.Y;
        Z = A.Z;
    }
    

    // Scalar multiplication
    Vector3D operator *(const float f)
    {
        Vector3D V(*this);
        V *= f;
        return V;
    }

    // Vector scale
    void operator *=(float f)
    {
        X *= this.f;
        Y *= this.f;
        Z *= this.f;
    }

float X, Y, Z;
};

int main () {


 Vector3D p2(1.0f, 2.0f, 3.0f);  // Constructor
    Vector3D q2(2.0f);
    Vector3D r2 = p2 * q2;   
                     
    std::cout << fixed << setprecision(2);
    cout << setw(5) << r2.X << "," << setw(5) << r2.Y << "," << setw(5) << r2.Z << endl;
    
    return 0;

CodePudding user response:

You can declare the operator * as a member function of the class or as a non-member function.

For example

class Vector3D {
public:
    Vector3D operator *( const Vector3D &v ) const 
    {
        return { X * v.X, Y * v.Y, Z * v.Z };
    }

    //...
};

Or as a non-member function

    Vector3D operator *( const Vector3D &v1, const Vector3D &v2 )
    {
        return { v1.X * v2.X, v1.Y * v2.Y, v1.Z * v2.Z };
    }

Pay attention to that this declaration in main

Vector3D q2(2.0f);

is incorrect because the class does not have a constructor with one parameter.

CodePudding user response:

In order to support scaling using a float, you could add a converting constructor that converts a float into a Vector3D where all axis are initialized to that float value:

class Vector3D {
public:
    Vector3D() : X(0), Y(0), Z(0) {};
    Vector3D(float A) : X(A), Y(A), Z(A) {}  // Added converting constructor
    Vector3D(float X, float Y, float Z) : X(X), Y(Y), Z(Z) {}

    // return *this to allow chaining expressions:
    Vector3D& operator*=(const Vector3D& A) {
        X *= A.X;
        Y *= A.Y;
        Z *= A.Z;
        return *this;
    }
    Vector3D operator*(const Vector3D& A) const {
        Vector3D V(*this); // using the implicitly defined copy constructor
        V *= A;            // using operator*= above
        return V;
    }

    float X, Y, Z;
};

If you now do

Vector3D p2(1.0f, 2.0f, 3.0f);
p2 *= 2.f;          // implicit conversion of 2.f into a Vector3d
auto p3 = p2 * 2.f; // implicit conversion of 2.f into a Vector3d

it will first create a temporary Vector3D with 2.f on every axis and then call Vector3D& operator*=(const Vector3D& A) on p2. p3 will be created using Vector3D operator*(const Vector3D& A) const - also after having converted 2.f into a Vector3D.

You may want to support Vector3D foo = 2.f * vec3d; too, where the float is on the left hand side in the multiplication. In that case, you need to add a free function:

Vector3D operator*(float f, const Vector3D& rhs) {
    return rhs * f; // just swap the order of the operands here
}

Demo

  • Related