0

I have a class in a header file which i am using mainly for the helper functions for vector manipulations (operator overloading of addition subtraction...etc) with the same class I have also another function and constructors used for when I define a new type this is the file below.

#pragma once

#include <math.h>
#include <assert.h>

class Vector2
{
public:
    union
{
    float Element[2];
    struct { float X, Y; };
    struct { float U, V; };
};

public:
    Vector2() {}

Vector2(float p_fValue)
: X(p_fValue), Y(p_fValue) {}

Vector2(float p_x, float p_y)
: X(p_x), Y(p_y) {}

Vector2(const Vector2 &p_vector)
: X(p_vector.X), Y(p_vector.Y) {}

float operator[](int p_nIndex) const { return Element[p_nIndex]; }
float& operator[](int p_nIndex) { return Element[p_nIndex]; }

inline void Set(float p_x, float p_y) {
    X = p_x; Y = p_y;
}

inline bool Equals(const Vector2 &p_vector, const float p_epsilon = 1e-5f) const
{
    if (fabs(X - p_vector.X) > p_epsilon) return false;
    if (fabs(Y - p_vector.Y) > p_epsilon) return false;

    return true;
}

Vector2& operator=(const Vector2 &p_vector)
{
    X = p_vector.X;
    Y = p_vector.Y;

    return *this;
}

inline bool operator==(const Vector2 &p_vector) const {
    return Equals(p_vector);
}

inline bool operator!=(const Vector2& p_vector) const {
    return !(*this == p_vector);
}

inline Vector2 operator*(float p_fValue) const {
    return Vector2(p_fValue * X, p_fValue * Y);
}

inline Vector2 operator/(float p_fValue) const
{
    assert(p_fValue != 0.f);
    return Vector2(*this * (1.0f / p_fValue));
}

inline Vector2 operator*(const Vector2 &p_vector) const {
    return Vector2(p_vector.X * X, p_vector.Y * Y);
}

inline Vector2 operator+(const Vector2 &p_vector) const {
    return Vector2(X + p_vector.X, Y + p_vector.Y);
}

inline Vector2 operator-(const Vector2 &p_vector) const {
    return Vector2(X - p_vector.X, Y - p_vector.Y);
}

inline Vector2 operator-(void) const {
    return Vector2(-X, -Y);
}

inline Vector2& operator*=(float p_fValue) {
    return *this = *this * p_fValue;
}

inline Vector2& operator*=(const Vector2 &p_vector) {
    return *this = *this * p_vector;
}

inline Vector2& operator/=(float p_fValue) {
    return *this = *this / p_fValue;
}

inline Vector2& operator+=(const Vector2 &p_vector) {
    return *this = *this + p_vector;
}

inline Vector2& operator-=(const Vector2 &p_vector) {
    return *this = *this - p_vector;
}

inline float MaxComponent() const {
    return std::max(X, Y);
}

inline float MinComponent() const {
    return std::min(X, Y);
}

inline float MaxAbsComponent() const {
    return std::max(fabs(X), fabs(Y));
}

inline float MinAbsComponent() const
{
    return std::min(fabs(X), fabs(Y));
}

static Vector2 Max(const Vector2 &p_vector1, const Vector2 &p_vector2)
{
    return Vector2(std::max(p_vector1.X, p_vector2.X),
                   std::max(p_vector1.Y, p_vector2.Y));
}

static Vector2 Min(const Vector2 &p_vector1, const Vector2 &p_vector2)
{
    return Vector2(std::min(p_vector1.X, p_vector2.X),
                   std::min(p_vector1.Y, p_vector2.Y));
}

inline float Length(void) const {
    return sqrt(X * X + Y * Y);
}

inline float LengthSquared(void) const {
    return X * X + Y * Y;
}

inline void Normalize(void) {
    *this = Vector2::Normalize(*this);
}

inline float Dot(const Vector2 &p_vector) const {
    return Vector2::Dot(*this, p_vector);
}

inline float AbsDot(const Vector2 &p_vector) const {
    return Vector2::AbsDot(*this, p_vector);
}

static float Dot(const Vector2 &p_vector1, const Vector2 &p_vector2) {
    return p_vector1.X * p_vector2.X + p_vector1.Y * p_vector2.Y;
    }

 static float AbsDot(const Vector2 &p_vector1, const Vector2 &p_vector2) {
    return fabs(p_vector1.X * p_vector2.X +
                p_vector1.Y * p_vector2.Y);
 }

 static Vector2 Normalize(const Vector2 &p_vector) {
        return p_vector / sqrt(p_vector.Length());
 }

 static float DistanceSquared(const Vector2 &p_point1, const Vector2 &p_point2) {
      return (p_point2 - p_point1).LengthSquared();
 }

 static float Distance(const Vector2 &p_point1, const Vector2 &p_point2) {
        return (p_point2 - p_point1).Length();
 }
};

inline Vector2 operator*(float p_fValue, const Vector2 &p_vector) {
    return Vector2(p_fValue * p_vector.X, p_fValue * p_vector.Y);
}

This is quite a trivial and there is probably not much more to add to this code it is just that I want the above code to be divided into a struct with the constructors and a class with the helper functions. Thats all.

bcsta
  • 1,963
  • 3
  • 22
  • 61
  • Why not just moving all those inline declarations to a separate translation unit? – πάντα ῥεῖ Dec 27 '16 at 19:58
  • how would that work? Im open to options since i'm new to this. if you can post an answer i will try it and will give it a thumbs up – bcsta Dec 27 '16 at 20:03
  • and also what abput the non inline functions? – bcsta Dec 27 '16 at 20:04
  • What exactly do you mean _class of helper functions_? You usually don't need a class to aggregate these. – πάντα ῥεῖ Dec 27 '16 at 20:06
  • Ok, so you want two files describing the same class, one where you put constructors and another where there are the other functions, and then they're stitched together into a complete class? – user Dec 27 '16 at 20:08
  • @user7331538 What do you want to achieve with that code? It looks pretty nonsensical for me. – πάντα ῥεῖ Dec 27 '16 at 20:08
  • @the reason being is that in my main code i am using MPI parallelism and that tends not to always work with classes that is why I need a struct – bcsta Dec 27 '16 at 20:10
  • @PatLaugh yes that is basically it. they don't have to be separate files i think it will work by having a struct and a class in the same header file right? well if not 2 files then – bcsta Dec 27 '16 at 20:11
  • @πάνταῥεῖ what i mean by helper functions are the functions you are seeing there in the header file for example `Vector2& operator=()` – bcsta Dec 27 '16 at 20:48

1 Answers1

0

Only way I can see is to use inheritance.

Make Vector2 a base class that you won't use, then make another class that inherits everything from it where helper functions are implemented.

struct Vector2Base
{
    union
    {
        float Element[2];
        struct { float X, Y; };
        struct { float U, V; };
    }
};

struct Vector2 : public Vector2Base
{
    Vector2& operator=(const Vector2 &p_vector)
    {
        X = p_vector.X;
        Y = p_vector.Y;

        return *this;
    }
};

Then you only use the derived class and never the base class.

user
  • 675
  • 4
  • 11
  • but as i said in the comment, I want to use structs since MPI implementations work best with structs – bcsta Dec 27 '16 at 21:53
  • I edited to put structs, but in C++, structs and classes are basically the same thing: http://stackoverflow.com/questions/92859/what-are-the-differences-between-struct-and-class-in-c – user Dec 27 '16 at 22:06