So i'm very new to c++ and i'm trying to test out the simple features it has. I currently have a problem that there is a 'class' type redefinition and I can't figure out why. I have used #pregama once in the header file, but still. I have even tried #ifndef and #define, but they did not work either. I'm using Visual studio 2019 community if that has anything to do with this.
Main.cpp
#include <iostream>
#include "Vectors.h"
using namespace std;
int main() {
double distance = Vector2::Zero().Distance(Vector2(1, 1));
cout << distance;
return 0;
}
Vector2.cpp
#include "Vectors.h"
#include <cmath>
class Vector2 {
public:
double x;
double y;
Vector2(double x, double y) {
this->x = x;
this->y = y;
}
static Vector2 Zero() {
return Vector2(0, 0);
}
static Vector2 One() {
return Vector2(1, 1);
}
double Distance(Vector2 other) {
Vector2 relPos = this->operator-(other);
relPos.x = abs(relPos.x);
relPos.y = abs(relPos.y);
return sqrt(pow(relPos.x, 2) + pow(relPos.y, 2));
}
Vector2 operator + (Vector2 vec) {
return Vector2(x + vec.x, y + vec.y);
}
Vector2 operator - (Vector2 vec) {
return Vector2(x - vec.x, y - vec.y);
}
Vector2 operator * (Vector2 vec) {
return Vector2(x * vec.x, y * vec.y);
}
Vector2 operator / (Vector2 vec) {
return Vector2(x / vec.x, y / vec.y);
}
};
Vectors.h
#pragma once
class Vector2 {
public:
Vector2(double x, double y);
static Vector2 Zero();
static Vector2 One();
double Distance(Vector2 other);
Vector2 operator + (Vector2 vec);
Vector2 operator - (Vector2 vec);
Vector2 operator * (Vector2 vec);
Vector2 operator / (Vector2 vec);
};
You're defining the class once in the header and once in the C++ file. You don't want to do class Vector2 { in the C++ file. Your functions should look like this
Vector2 Vector2::operator+(Vector2 vec) {
return Vector2(x + vec.x, y + vec.y);
}
And should be defined at top-level scope in the C++ file.
First of all, I agree with Silvio Mayolo, You're defining the class once in the header and once in the C++ file. You don't use the keyword class in your cpp file.
And then you need to distinguish between class Vector2 and Vector2(double x, double y); As far as I'm concerned you should try to use Vector2::.
Here is my code:
Vectors.h:
#pragma once
class Vector2 {
public:
double x;
double y;
Vector2(double x, double y);
static Vector2 Zero();
static Vector2 One();
double Distance(Vector2 other);
Vector2 operator + (Vector2 vec);
Vector2 operator - (Vector2 vec);
Vector2 operator * (Vector2 vec);
Vector2 operator / (Vector2 vec);
};
Vector2.cpp:
#include "Vectors.h"
#include <cmath>
double x;
double y;
Vector2::Vector2(double x, double y)
{
this->x = x;
this->y = y;
}
Vector2 Vector2::Zero() {
return Vector2(0, 0);
}
Vector2 Vector2::One() {
return Vector2(1, 1);
}
double Vector2::Distance(Vector2 other) {
Vector2 relPos = this->operator-(other);
relPos.x = abs(relPos.x);
relPos.y = abs(relPos.y);
return sqrt(pow(relPos.x, 2) + pow(relPos.y, 2));
}
Vector2 Vector2::operator + (Vector2 vec) {
return Vector2(x + vec.x, y + vec.y);
}
Vector2 Vector2::operator - (Vector2 vec) {
return Vector2(x - vec.x, y - vec.y);
}
Vector2 Vector2::operator * (Vector2 vec) {
return Vector2(x * vec.x, y * vec.y);
}
Vector2 Vector2::operator / (Vector2 vec) {
return Vector2(x / vec.x, y / vec.y);
}
Main.cpp:
#include <iostream>
#include "Vectors.h"
using namespace std;
int main() {
double distance = Vector2::Zero().Distance(Vector2(1, 1));
cout << distance;
return 0;
}
Related
I am experimenting with lambda functions and managed to recreate a "get" functionality in C++. I can get the return value of a function without using parentheses. This is an example class, where I implement this:
using namespace std;
struct Vector2 {
float x;
float y;
float length = [&]()-> float {return sqrt(x * x + y * y); }();
float angle = [&]()-> float {return atan2(y, x); }();
Vector2() : x(0), y(0) {}
Vector2(float a, float b) : x(a), y(b) {}
~Vector2() {}
Vector2(Vector2& other) : x(other.x), y(other.y) {}
Vector2(Vector2&& other) = delete;
void operator =(Vector2&& other) noexcept{
x = other.x;
y = other.y;
}
};
int main()
{
Vector2 vec = Vector2(10, 17);
printf("%f\n%f\n%f\n%f\n", vec.x, vec.y, vec.length, vec.angle);
}
However, I am currently trying to also recreate the "set" functionality that C# has. But I'm failing. I tried to add this:
void angle = [&](float a)->void {
float l = length;
x = cos(a) * l;
y = sin(a) * l;
};
But am getting "Incomplete type is not allowed" error. I'm not sure if that's how it should look, even if I wasn't getting the error. Is it even possible to recreate the "set" functionality C# has in C++?
I know that I can just use a method SetAngle(float a){...}, but that's not really the point.
TL;DR: Don't
What you have isn't a getter, it's just a normal data member that's calculated once when the object is initialized.
In general, C++ doesn't support C#-style properties. The usual C++-style solution is to just use a pair of member functions (and maybe a data member, if you need to save the value separately), i.e.
struct Vector2 {
// ...
float length() const { return sqrt(x * x + y * y); }
void length(float l) {
float angle = angle();
float new_x = l * cos(angle);
float new_y = l * sin(angle);
x = new_x;
y = new_y;
}
// ...
};
You can get something close to a C#-style property, but you'll always run into edge-cases where they don't work perfectly. For example, here's something that will work in many cases:
template <typename T>
class Property
{
private:
std::function<T()> getter_;
std::function<void(const T&)> setter_;
public:
Property(std::function<T()> getter, std::function<void(const T&)> setter)
: getter_{getter},
setter_{setter}
{}
operator T()
{
return getter_();
}
const T& operator=(const T& val)
{
setter_(val);
return val;
}
};
struct Vector2
{
float x;
float y;
Property<float> length{
[this]() { return sqrt(x * x + y * y); },
[this](float l) {
float new_x = l * cos(angle);
float new_y = l * sin(angle);
x = new_x;
y = new_y;
}
}
Property<float> angle{
[this]() { return atan2(y, x); },
[this](float a) {
float l = length;
x = cos(a) * l;
y = sin(a) * l;
}
}
// ...
};
int main() {
Vector2 v;
v.x = 1;
v.y = 1;
v.angle = std::numbers::pi / 2;
std::cout << "(" << v.x << ", " << v.y << ")\n";
}
But this still falls apart in the edge cases, especially when you mix it with templates and/or auto type-deduction. For instance:
Vector2 v;
v.x = 1;
v.y = 1;
auto old_angle = v.angle;
v.angle = std::numbers::pi / 2;
// oops, this prints pi/2, not pi/4 like you probably expected
// because old_angle isn't a float, it's a Property<float> that
// references v
std::cout << old_angle << '\n';
Note also that there's a bug here. Consider this:
int main() {
Vector2 v1;
v1.x = 1;
v1.y = 1;
Vector2 v2 = v1;
v2.angle = std::numbers::pi / 2;
// Oops, assigning to v2.angle modified v1
std::cout << "(" << v1.x << ", " << v1.y << ")\n";
}
You could work around these issues by making Property non-copyable, but then you force any class that uses it to implement a custom copy-constructor. Also, while that would make the auto case "safe", it does so by turning it into a compile error. Still not ideal.
I agree with Miles. This is not the greatest idea, because it's unnatural for C++ developers, and you should write code that is first and foremost easy to read.
However, as an engineering challenge, here's a possible implementation:
#include <math.h>
#include <iostream>
template <typename T>
class Member
{
public:
operator T() const { return _value; }
void operator =(const T& value) const { _value = value; } void operator =(T&& value) { _value = std::move(value); }
private:
T _value;
};
class Angle
{
public:
Angle(const Member<float>& x, const Member<float>& y) :
_x(x), _y(y) {}
operator float() const { return atan2(_y, _x); }
private:
const Member<float>& _x, _y;
};
class Obj
{
public:
Member<float> x, y;
Angle angle;
Obj() : angle(this->x, this->y) {}
};
int main()
{
Obj o;
o.x = 3;
o.y = 5;
std::cout << o.x << ", " << o.y << " -> " << o.angle << std::endl;
}
While other solutions also seem to be possible, this one seems to be the most elegant :P
using namespace std;
struct Vector2 {
float x;
float y;
float init_length = [&]()-> float {return sqrt(x * x + y * y); }();
float init_angle = [&]()-> float {return atan2(y, x); }();
__declspec(property(get = GetAngle, put = SetAngle)) float angle;
__declspec(property(get = GetLength, put = SetLength)) float length;
Vector2() : x(0), y(0) {}
Vector2(float a, float b) : x(a), y(b) {}
~Vector2() {}
Vector2(Vector2& other) : x(other.x), y(other.y) {}
Vector2(Vector2&& other) = delete;
void operator =(Vector2&& other) = delete;
void Display() {
printf("%f\n%f\n%f\n%f\n\n", x, y, length, angle);
}
float GetLength() {
return sqrt(x * x + y * y);
}
float GetAngle() {
return atan2(y, x);
}
void SetLength(float l) {
float a = GetAngle();
x = cos(a) * l;
y = sin(a) * l;
}
void SetAngle(float a) {
float l = GetLength();
x = cos(a) * l;
y = sin(a) * l;
}
};
int main()
{
Vector2 vec = Vector2(10, 17);
vec.Display();
vec.length = 5;
vec.Display();
}
I've been having trouble trying to implement objects from class Cart_Vector in class Cart_Point. My compiler has been listing the following errors and I can't seem to fix them:
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
'Cart_Vector' does not name a type
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
'Cart_Vector' does not have a type
x = p1.x + v1.x; request for member 'x' in 'v1', which is of non-class
type 'const int'
y = p1.y + v1.y; request for member 'y' in 'v1', which is of non-class
type 'const int'
return Cart_Vector(x,y); 'Cart_Vector' was not declared in this scope
#include <iostream>
#include <math.h>
using namespace std;
class Cart_Point
{
public:
double x;
double y;
friend class Cart_Vector;
Cart_Point (double inputx, double inputy);
friend Cart_Point operator<<(const Cart_Point&p1, const Cart_Point&p2);
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
friend Cart_Point operator-(const Cart_Point&p1,const Cart_Point&p2);
double Cart_distance(Cart_Point, Cart_Point);
};
Cart_Point::Cart_Point(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
double Cart_Point::Cart_distance(Cart_Point p1, Cart_Point p2)
{
double distance = (sqrt( pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) ));
return distance;
//returns distance between p1 (point 1) and p2 (point 2)
}
Cart_Point operator<<(const Cart_Point&p1, const Cart_Point&p2)
{
cout << "p1:(" << p1.x << ", " << p1.y << ")" << endl;
cout << "p2:(" << p2.x << ", " << p2.y << ")" << endl;
return p1,p2;
//this function should just print each point
}
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
{
double x,y;
x = p1.x + v1.x;
y = p1.y + v1.y;
return Cart_Point(x,y);
//this function should make a new Cart_Point
}
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
class Cart_Vector
{
public:
double x; //x displacement of vector
double y; //y displacement of vector
Cart_Vector(double inputx, double inputy);
friend Cart_Vector operator*(const Cart_Vector&v1, double d);
friend Cart_Vector operator/(const Cart_Vector&v1, double d);
Cart_Vector operator<<(const Cart_Vector&v1);
friend class Cart_Point;
};
Cart_Vector::Cart_Vector(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
Cart_Vector operator*(const Cart_Vector&v1, double d)
{
double x,y;
x = v1.x*d;
y = v1.y*d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
Cart_Vector operator/(const Cart_Vector&v1, double d)
{
double x,y;
if (d == 0)
{
x = v1.x;
y = v1.y;
}
x = v1.x/d;
y = v1.y/d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector and dividing by zero creates v1
}
Cart_Vector Cart_Vector::operator<<(const Cart_Vector&v1)
{
cout <<"v1: <" << v1.x << ", " << ">" << endl;
return v1;
//this function should just print v1
}
//TestCheckpoint1.cpp file below
int main()
{
//I haven't finished the main function to test all the functions yet
return 0;
}
split your code in different files but your implementation of operator << is wrong , consider following code , its just a hint to help
#include <iostream>
#include <math.h>
using namespace std;
class Cart_Vector
{
public:
double x; //x displacement of vector
double y; //y displacement of vector
Cart_Vector(double inputx, double inputy);
friend Cart_Vector operator*(const Cart_Vector&v1, double d);
friend Cart_Vector operator/(const Cart_Vector&v1, double d);
friend std::ostream& operator<<( std::ostream& out,const Cart_Vector&v1);
friend class Cart_Point;
};
Cart_Vector::Cart_Vector(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
Cart_Vector operator*(const Cart_Vector&v1, double d)
{
double x,y;
x = v1.x*d;
y = v1.y*d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
Cart_Vector operator/(const Cart_Vector&v1, double d)
{
double x,y;
if (d == 0)
{
x = v1.x;
y = v1.y;
}
x = v1.x/d;
y = v1.y/d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector and dividing by zero creates v1
}
std::ostream& operator<<(std::ostream &out, const Cart_Vector&v1)
{
out <<"v1: <" << v1.x << ", " << ">" << endl;
return out;
//this function should just print v1
}
class Cart_Point
{
public:
double x;
double y;
friend class Cart_Vector;
Cart_Point (double inputx, double inputy);
friend std::ostream& operator<<(std::ostream& out , const Cart_Point&p2);
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
friend Cart_Point operator-(const Cart_Point&p1,const Cart_Point&p2);
double Cart_distance(Cart_Point, Cart_Point);
};
Cart_Point::Cart_Point(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
double Cart_Point::Cart_distance(Cart_Point p1, Cart_Point p2)
{
double distance = (sqrt( pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) ));
return distance;
//returns distance between p1 (point 1) and p2 (point 2)
}
std::ostream& operator<<(std::ostream &out, const Cart_Point&p1)
{
// Since operator<< is a friend of the Cart_Point class, we can access Point's members directly.
out << "p:(" << p1.x << ", " << p1.y << ")" << endl;
return out;
//this function should just print each point
}
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
{
double x,y;
x = p1.x + v1.x;
y = p1.y + v1.y;
return Cart_Point(x,y);
//this function should make a new Cart_Point
}
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
return Cart_Point(x,y);
//this function should make a new Cart_Vector
}
//TestCheckpoint1.cpp file below
int main()
{
Cart_Point point1(2.0, 3.0);
std::cout << point1;
//I haven't finished the main function to test all the functions yet
return 0;
}
Wandbox :
Do yourself a favor and split your code in different files,at least one .h for Cart_Vector, one .h for Cart_Point, and one .cpp for the test script (main). You can correct this code to make it work (just swap the order of the two classes), if you correct other errors too, like in the overloading of the operator "-".
The point here is that if you start coding in this way, when you start programming complex projects you will find yourself in great difficulties. Coding one public (non-inner) class-per file is like applying Single Responsibility Principle for files too. I would say that also a file should have only one reason to change, and this has great benefits in readability and when will you perform version control.
Cart_Vector and Cart_point need each other. So you need to implement these classes in separate header files. Do not forget include them. Also in here ;
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
//return Cart_Vector(x,y);
return Cart_Pointer(x,y);
//this function should make a new Cart_Vector
}
You can not access non-const elements of const object and you can not call non-const functions. You can pass these objects by value if you want it.
I'm having an issue with the inheritance of my operator overloading functions in my derived class.
#pragma once
#include "Math.hpp"
using namespace Math;
class Euler
{
public:
float x, y, z;
Euler();
Euler(const float &, const float &, const float &);
float &operator[](const char &) const;
Euler &operator=(const Euler &);
Euler &operator+=(const Euler &);
Euler &operator-=(const Euler &);
Euler &operator*=(const float &);
Euler &operator/=(const float &);
Euler operator+(const Euler &) const;
Euler operator-(const Euler &) const;
Euler operator*(const float &) const;
Euler operator/(const float &) const;
bool operator==(const Euler &) const;
bool operator!=(const Euler &) const;
bool IsValid() const;
void Clear();
};
inline Euler::Euler()
{
x = y = z = 0.f;
}
inline Euler::Euler(const float &_x, const float &_y, const float &_z)
{
x = _x;
y = _y;
z = _z;
}
inline float &Euler::operator[](const char &c) const
{
return ((float *)this)[c];
}
inline Euler &Euler::operator=(const Euler &e)
{
x = e.x;
y = e.y;
z = e.z;
return *this;
}
inline Euler &Euler::operator+=(const Euler &e)
{
x += e.x;
y += e.y;
z += e.z;
return *this;
}
inline Euler &Euler::operator-=(const Euler &e)
{
x -= e.x;
y -= e.y;
z -= e.z;
return *this;
}
inline Euler &Euler::operator*=(const float &e)
{
x *= e;
y *= e;
z *= e;
return *this;
}
inline Euler &Euler::operator/=(const float &e)
{
x /= e + M_FLT_EPSILON;
y /= e + M_FLT_EPSILON;
z /= e + M_FLT_EPSILON;
return *this;
}
inline Euler Euler::operator+(const Euler &e) const
{
return Euler(x + e.x, y + e.y, z + e.z);
}
inline Euler Euler::operator-(const Euler &e) const
{
return Euler(x - e.x, y - e.y, z - e.z);
}
inline Euler Euler::operator*(const float &f) const
{
return Euler(x * f, y * f, z * f);
}
inline Euler Euler::operator/(const float &f) const
{
return Euler(x / (f + M_FLT_EPSILON), y / (f + M_FLT_EPSILON), z / (f + M_FLT_EPSILON));
}
inline bool Euler::operator==(const Euler &e) const
{
return e.x == x && e.y == y && e.z == z;
}
inline bool Euler::operator!=(const Euler &e) const
{
return e.x != x || e.y != y || e.z != z;
}
inline bool Euler::IsValid() const
{
using namespace std;
return isfinite(x) && isfinite(y) && isfinite(z);
}
inline void Euler::Clear()
{
x = y = z = 0.f;
}
class Vector : public Euler
{
public:
using Euler::Euler;
void Rotate(const Angle &);
void Rotate2D(const float &);
float Length() const;
float LengthSqr() const;
float Length2D() const;
float Length2DSqr() const;
float DistTo(const Vector &) const;
float DistToSqr(const Vector &) const;
};
inline float Vector::Length() const
{
return Sqrt((x * x) + (y * y) + (z * z));
}
inline float Vector::LengthSqr() const
{
return (x * x) + (y * y) + (z * z);
}
inline float Vector::Length2D() const
{
return Sqrt((x * x) + (y * y));
}
inline float Vector::Length2DSqr() const
{
return (x * x) + (y * y);
}
inline float Vector::DistTo(const Vector &v) const
{
return (*this - v).Length();
}
inline float Vector::DistToSqr(const Vector &v) const
{
return (*this - v).LengthSqr();
}
The code shown below contains an error in the distto and DistToSqr function wherein it calculates (*this - v) as the superclass Euler and therefore cannot find the length function.
I was wondering why this would be as this code compiles on my laptop and not my desktop.
I'd be grateful if anyone could show me why this code doesn't work and what is the best course in fixing it.
It seems like doing this is a plausible way to fix it.
inline float Vector::DistTo(const Vector &v) const
{
Vector tmp = (*this - v);
return tmp.Length();
}
Still wondering if this is the best option to fix it though.
I'm going to assume that it is likely that Euler is always used as a base type of a more specific type? If so, you can might be able to solve this using the CRTP pattern. Here is a subset of your code in this style:
#include <cmath>
template <typename Derived>
class Euler
{
public:
float x, y, z;
Euler();
Euler(const float &, const float &, const float &);
template <typename T>
Derived & operator-=(Euler<T> const &);
template <typename T>
Derived operator-(Euler<T> const &) const;
private:
Derived & derived() const {
return static_cast<Derived &>(*this);
}
Derived const & derived() {
return static_cast<Derived const &>(*this);
}
};
template <typename Derived>
Euler<Derived>::Euler() : x(0), y(0), z(0)
{}
template <typename Derived>
Euler<Derived>::Euler(const float &_x, const float &_y, const float &_z)
: x(_x), y(_y), z(_z)
{}
template <typename Derived>
template <typename T>
Derived & Euler<Derived>::operator-=(Euler<T> const & e)
{
x -= e.x;
y -= e.y;
z -= e.z;
return derived();
}
template <typename Derived>
template <typename T>
Derived Euler<Derived>::operator-(Euler<T> const & e) const
{
return Derived(x - e.x, y - e.y, z - e.z);
}
class Vector : public Euler<Vector>
{
public:
using Euler<Vector>::Euler;
float Length() const;
float DistTo(const Vector &) const;
};
inline float Vector::Length() const
{
return std::sqrt(x * x + y * y + z * z);
}
inline float Vector::DistTo(const Vector & v) const
{
return (*this - v).Length();
}
To start off with, I'll mention I come mainly from a Java background. I do have exposure with C and understand most concepts behind C++. I'm trying to help myself learn more about the language and can't seem to figure out headers. I understand why to use them in addition to cpp files and all of that. My problem is trying to actually manage working with them. For example, defining a Vector3 header with private float variables and then overload operating. My problem comes in when I attempt to define the constructor and methods in the cpp file. I can't seem to figure out how to get access to the private variables without specifically defining the functions and the constructor in the header, which more or less leads me to believe I don't need both a header and cpp file in this instance.
Here's how I've defined the header file currently (which works, but isn't undefined as it should be):
#pragma once
#ifndef __Vector_3_H__
#define __Vector_3_H__
namespace VectorMath {
class Vector3 {
public:
Vector3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3 operator+(Vector3 vector) {
return Vector3(x + vector.x, y + vector.y, z + vector.z);
}
Vector3 operator-(Vector3 vector) {
return Vector3(x - vector.x, y - vector.y, z - vector.z);
}
Vector3 operator*(Vector3 vector) {
return Vector3(x * vector.x, y * vector.y, z * vector.z);
}
Vector3 operator/(Vector3 vector) {
return Vector3(x / vector.x, y / vector.y, z / vector.z);
}
float getX() {
return x;
}
float getY() {
return y;
}
float getZ() {
return z;
}
private:
float x;
float y;
float z;
};
}
#endif
It needs to look more like this instead:
Vector_3.h:
#ifndef Vector_3_H
#define Vector_3_H
#pragma once
namespace VectorMath {
class Vector3 {
public:
Vector3(float x, float y, float z);
Vector3 operator+(Vector3 vector);
Vector3 operator-(Vector3 vector);
Vector3 operator*(Vector3 vector);
Vector3 operator/(Vector3 vector);
float getX();
float getY();
float getZ();
private:
float x;
float y;
float z;
};
}
#endif
Vector_3.cpp:
#include "Vector_3.h"
namespace VectorMath {
Vector3::Vector3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3 Vector3::operator+(Vector3 vector) {
return Vector3(x + vector.x, y + vector.y, z + vector.z);
}
Vector3 Vector3::operator-(Vector3 vector) {
return Vector3(x - vector.x, y - vector.y, z - vector.z);
}
Vector3 Vector3::operator*(Vector3 vector) {
return Vector3(x * vector.x, y * vector.y, z * vector.z);
}
Vector3 Vector3::operator/(Vector3 vector) {
return Vector3(x / vector.x, y / vector.y, z / vector.z);
}
float Vector3::getX() {
return x;
}
float Vector3::getY() {
return y;
}
float Vector3::getZ() {
return z;
}
}
If you want to use a cpp file for your constructor you should write
// File Vector3.cpp
#include "Vector3.h"
namespace VectorMath {
Vector3::Vector3 (float x, float y, float z)
{
this->x=x;
//...
}
The addition should be implemented as follows if you keep it in the same namespace
Vector3 Vector3::operator+(const Vector3& v)
{
return Vector3 (x+v.x,y+v.y,z+v.z);
}
}
If you want to move the implementations of member functions away from the header file, you still need to declare them in the definition of the class. For example:
// Vector1.h
#pragma once
#ifndef VectorMath_Vector1_H
#define VectorMath_Vector1_H
namespace VectorMath {
class Vector1 {
public: // Methods:
// This is a definition for a default constructor:
Vector1() noexcept : m_x(0) {}
// This is a declaration for another constructor:
Vector1(float x) noexcept;
// This is a declaration of a member function:
Vector1 operator+(Vector1 const & rhs) const noexcept;
private: // Fields:
float m_x;
}; // class Vector1
} // namespace VectorMath {
#endif // VectorMath_Vector1_H
// Vector1.cpp
#include "Vector1.h"
namespace VectorMath {
// Definition of the other constructor:
Vector1::Vector1(float x) noexcept
: m_x(x)
{}
// Definition of the binary + operator:
Vector1 Vector1::operator+(Vector1 const & rhs) const noexcept
{ return m_x + rhs.m_x; }
} // namespace VectorMath {
So I'm following along with this book called SDL Game Development by Shaun Mitchell. I've ran into a few hiccups with code from the book but have so far been able to figure it out and correct on my own but this one has got me in a bind.
The program compiles fine but crashes with a seg fault.
This is the Vector2D class that the book has me write:
#ifndef __Vector2D__
#define __Vector2D__
#include <math.h>
class Vector2D
{
public:
Vector2D(float x, float y) : m_x(x), m_y(y) {}
float getX() { return m_x; }
float getY() { return m_y; }
void setX(float x) { m_x = x; }
void setY(float y) { m_y = y; }
float length() { return sqrt(m_x * m_x + m_y * m_y); }
Vector2D operator+(const Vector2D& v2) const
{
return Vector2D(m_x + v2.m_x, m_y + v2.m_y);
}
friend Vector2D& operator+=(Vector2D& v1, const Vector2D& v2)
{
v1.m_x += v2.m_x;
v1.m_y += v2.m_y;
return v1;
}
Vector2D operator*(float scalar)
{
return Vector2D(m_x * scalar, m_y * scalar);
}
Vector2D& operator*=(float scalar)
{
m_x *= scalar;
m_y *= scalar;
return *this;
}
Vector2D operator-(const Vector2D& v2) const
{
return Vector2D(m_x - v2.m_x, m_y - v2.m_y);
}
friend Vector2D& operator-=(Vector2D& v1, const Vector2D& v2)
{
v1.m_x -= v2.m_x;
v1.m_y -= v2.m_y;
return v1;
}
Vector2D operator/(float scalar)
{
return Vector2D(m_x / scalar, m_y / scalar);
}
Vector2D& operator/=(float scalar)
{
m_x /= scalar;
m_y /= scalar;
return *this;
}
void normalize()
{
float l = length();
if (l > 0)
{
(*this) *= 1 / 1;
}
}
private:
float m_x;
float m_y;
};
#endif // __Vector2D__
This is a Player class' input handling event where the program begins to crash:
void Player::handleInput()
{
Vector2D* vec = TheInputHandler::Instance()->getMousePosition();
m_velocity = (*vec - m_position) / 100;
}
It crashes at m_velocity = (*vec - m_position) / 100; which of course traces back to my Vector2D class' operator-. m_velocity and m_position are both Vector2Ds. Replacing the - with + produces the same crash.
Any help with what may be wrong would be super appreciated.
Vector2D* vec = TheInputHandler::Instance()->getMousePosition();
You made it a pointer, but never allocated memory for it. (unless that's what that function does..?)
There is no need to make this a pointer if you're not going to pass it anywhere.