C++ Object Instantiation In a class file - c++

I am making a module/library with a vector class, and I want it to do it properly.
class Vector3 {
public:
float x, y, z;
public:
Vector3();
Vector3(float a, float b, float c);
float length();
void normalize();
Vector3* dotproduct(Vector3 *rhs);
Vector3* crossproduct(Vector3 *rhs);
Vector3* add(Vector3 *rhs);
Vector3* subtract(Vector3 *rhs);
};
My doubt is in how should I return a new Vector3 after an operation.
Currently, I am dynamically allocating a new Vector3 inside each operation and then I return it.
When I use the operation I have:
Vector3 *v = v2->crossproduct(v3);
Should I change my operations to:
Vector3 Vector3::crossproduct(Vector3 *rhs){
float a = y * rhs->z - z * rhs->y;
float b = z * rhs->x - x * rhs->z;
float c = x * rhs->y - y * rhs->x;
Vector3 res(a, b, c);
return res ;
}
And use:
Vector3 v = v2->crossproduct(v3);
Or will I eventually lose the vector?
Since I'm trying to make a library what is the proper way to do it?
Allocate at the stack, or in the heap?

I implemente these operations like this:
Vector3 Vector3::crossproduct(const Vector3& rhs){
float a = y * rhs.z - z * rhs.y;
float b = z * rhs.x - x * rhs.z;
float c = x * rhs.y - y * rhs.x;
Vector3 res(a, b, c);
return res ;
}
To use this operator you can simply use this syntax:
Vector v1, v2;
auto product = v1.crossproduct(v2);
The return as value is most likely optimized away by copy elision, so you dont have to worry about that. And since rhs is not modified, passing it as const ref& is the fastest way to do it.

Related

No operator = match these operands c++ even though said operator has been overloaded

I am trying to do a multiplication for my vector class and my matrix class.
Vector2f Matrix3x3::operator * (Vector2f & v) {
float vx = e11 * v.x + e21 * v.y + e31;
float vy = e12 * v.x + e22 * v.y + e32;
return Vector2f(vx, vy);
}
When a matrix multiplies with a vector it should return a vector. So I try to set the result to an already created vector object.
Vector2f d(12, 12);
Matrix3x3 m = translationMatrix(transX, transY);
d = m * d;
VS keeps underlining my "=" and says that no operators = match these operands, operands type are Vector2f and Vector2f. Even though I already overload assignment operator in Vector2f class
Vector2f & Vector2f::operator = (Vector2f & V) {
x = V.x;
y = V.y;
return *this;
}
I dont even know where I am wrong. Can someone explain it to me?
Matrix3x3::operator * returns by value, which means the object returned by m * d is a temporary, which can't be bound to lvalue-reference to non-const (i.e. Vector2f &); but it can be bound to lvalue-reference to const (i.e. const Vector2f &).
To solve the issue you chould change the parameter type of operator= to const Vector2f &, and you should do this also because the argument is supposed to be not modified inside operator=.
Vector2f & Vector2f::operator = (const Vector2f & V) {
x = V.x;
y = V.y;
return *this;
}

Function Overloading Error When Overloading cmath function C++

I'm writing a simple C++ class called Vector2f. I have a class file called Vector2f.cpp and a header file called Vector2f.h.
My Vector2f class has a function called abs which returns a new Vector2f with the absolute value of each of the components of the original Vector2f. I am using the cmath library. However when I try to use cmath's abs function, it thinks I'm referring to some undefined function Vector2f::abs(float) rather than cmath's abs function. Why is there a naming conflict here? Shouldn't C++ be able to resolve that a function called abs that takes a float is only defined in cmath and not in Vector2f.h
Here is my code:
My header file:
//Vector2f.h
#ifndef VECTOR2F_H
#define VECTOR2F_H
class Vector2f
{
private:
float x;
float y;
public:
Vector2f(float x, float y);
float length();
float dot(Vector2f r);
Vector2f normalized();
Vector2f rot(float angle);
Vector2f add(Vector2f r);
Vector2f add(float r);
Vector2f sub(Vector2f r);
Vector2f sub(float r);
Vector2f mul(Vector2f r);
Vector2f mul(float r);
Vector2f div(Vector2f r);
Vector2f div(float r);
Vector2f abs();
float getX();
float getY();
};
#endif // VECTOR2F_H
My class file:
//Vector2f.cpp
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif // M_PI
#include "Vector2f.h"
#include <cmath>
Vector2f::Vector2f(float x, float y)
{
this -> x = x;
this -> y = y;
}
float Vector2f::length()
{
return (float)sqrt(x * x + y * y);
}
float Vector2f::dot(Vector2f r)
{
return x * r.getX() + y * r.getY();
}
Vector2f Vector2f::normalized()
{
float length = Vector2f::length();
float xnormal = x/length;
float ynormal = y/length;
return Vector2f(xnormal, ynormal);
}
Vector2f Vector2f::rot(float angle)
{
double rad = angle * M_PI / 180.0;
double c = cos(rad);
double s = sin(rad);
return Vector2f((float)(x * c - y * s), (float)(x * s + y * c));
}
Vector2f Vector2f::add(Vector2f r)
{
return Vector2f(x + r.getX(), y + r.getY());
}
Vector2f Vector2f::add(float r)
{
return Vector2f(x + r, y + r);
}
Vector2f Vector2f::sub(Vector2f r)
{
return Vector2f(x - r.getX(), y - r.getY());
}
Vector2f Vector2f::sub(float r)
{
return Vector2f(x - r, y - r);
}
Vector2f Vector2f::mul(Vector2f r)
{
return Vector2f(x * r.getX(), y * r.getY());
}
Vector2f Vector2f::mul(float r)
{
return Vector2f(x * r, y * r);
}
Vector2f Vector2f::div(Vector2f r)
{
return Vector2f(x / r.getX(), y / r.getY());
}
Vector2f Vector2f::div(float r)
{
return Vector2f(x / r, y / r);
}
Vector2f Vector2f::abs()
{
//I get the error, "error: no matching function for call to 'Vector2f::abs(float&)'", here
//when trying to call abs(x) and abs(y)
float xabs = abs(x);
float yabs = abs(y);
return Vector2f(xabs, yabs);
}
float Vector2f::getX()
{
return x;
}
float Vector2f::getY()
{
return y;
}
My main file:
//main.cpp
#include <iostream>
#include "Vector2f.h"
using namespace std;
int main()
{
Vector2f a(1.0f,2.0f);
cout<<a.getX()<<','<<a.getY()<<endl;
cout<<a.abs()<<endl;
return 0;
}
Any help would be appreciated.
Edit:
Error message:
error: no matching function for call to 'Vector2f::abs(float&)'
at line 80:
float xabs = abs(x);
error: no matching function for call to 'Vector2f::abs(float&)'
at line 81:
float yabs = abs(y);
The compiler does an unqualified lookup of abs. What happens then depends on what you include and if there is a using declaration (and interestingly on the compiler). Everything in cmath is defined in namespace std, so you have to qualify your call with std::.
Vector2f Vector2f::abs()
{
//I get the error, "undefined reference to `Vector2f::abs(float)'", here
//when trying to call abs(x) and abs(y)
float xabs = std::abs(x);
float yabs = std::abs(y);
return Vector2f(xabs, yabs);
}
If you have a using std::abs or using namespace std somewhere before Vector2d::abs, you can qualify with ::abs only. Compilers are allowed to declare C functions such as abs in the global namespace in addition to namespace std, so depending on the compiler using ::abs may work or not without using declarations at all. Clang 3.8 accepts the code, gcc does not.
PS: I would expect a function Vector2f::abs to compute the vector norm and not a vector with absolute values of the original components. But then I am not a mathematician.

About 200 Errors When Using cmath in Visual Studio 2015

Trying to get code that was compilable in g++ to compile in VS2015. I looked around SO & Google with not much luck, yet cmath is documented in MSDN. I'm guessing I'm missing something really obvious or simple.
cmath is throwing a lot of errors most of the errors I'm getting during compilation, and half are in the form:
the global scope has no "<function>"
others are in the form
'<function>': redefinition; different exception specification
'<function>': identifier not found
'<function>': is not a member of "global namespace"
I don't understand why these errors are being thrown, but, if I use math.h, most of my compilation errors go away (including some in other standard libs that are crapping out, too).
Edit: As requested, the code. I'm using the sqrt & pow functions:
#include "vector.h"
#include <cmath>
using namespace vectormath;
vector::vector()
{
this->_x = 0;
this->_y = 0;
this->_z = 0;
this->_length = 0;
}
vector::vector(float x, float y, float z)
{
this->_x = x;
this->_y = y;
this->_z = z;
this->_length = sqrt(pow(_x, 2) + pow(_y, 2) + pow(_z, 2));
}
vector * vectormath::crossproduct(vector * a, vector * b)
{
vector * result = new vector();
result->_x = a->_y * b->_z - a->_z * b->_y;
result->_y = a->_z * b->_x - a->_x * b->_z;
result->_z = a->_x * b->_y - a->_y * b->_x;
return result;
}
point::point()
{
this->_x = 0.0;
this->_y = 0.0;
this->_z = 0.0;
}
point::point(float x, float y, float z)
{
this->_x = x;
this->_y = y;
this->_z = z;
}
float vectormath::dotproduct(vector a, vector b)
{
return a._x * b._x + a._y * b._y + a._z * b._z;
}
vector * vectormath::add(point * a, vector * b)
{
vector * c = new vector();
c->_x = a->_x + b->_x;
c->_y = a->_y + b->_y;
c->_z = a->_z + b->_z;
return c;
}
Edit: and vector.h
namespace vectormath
{
struct vector
{
float _x;
float _y;
float _z;
float _length;
vector();
vector(float x, float y, float z);
};
struct point
{
float _x;
float _y;
float _z;
point();
point(float x, float y, float z);
};
vector * crossproduct(vector*, vector*);
float dotproduct(vector a, vector b);
vector * add(point * a, vector * b);
}
The difference between
#include <math.h>
and
#include <cmath>
is that the former puts things like sqrt and pow into the global namespace (i.e., you refer to them just by saying sqrt or pow) and the latter puts them into namespace std (i.e., you refer to them by saying std::sqrt or std::pow).
If you want not to have to prefix them with std:: all the time, you can put individual ones in the global namespace explicitly:
using std::sqrt;
or (though this is not recommended) you can pull in the whole of std like this:
using namespace std;
The trouble with that is that there are a lot of names in std and you probably don't really want them all.

User defined calculation on structs/classes

I was once using Unity and they use a cool System to add and multiply vectors.
This is a short excerpt from the Reference (http://docs.unity3d.com/ScriptReference/Transform.html)
foreach (Transform child in transform) {
child.position += Vector3.up * 10.0F;
}
as you can see they can just add and multiply two Vectors (structs/classes) even though they could have different variables. Right now when I try to make such a calculation I have to add the x and y of a 2d float vector individually.
So how can i add structs like a
struct Vec2f{
float x;
float y;
};
together by writing
Vec2f c = a + b;
instead of
c.x = a.x + b.x;
c.y = a.y + b.y;
EDIT:
You need to overload operators like '+', '-' etc. in your struct. Example for addition:
struct Vec2f
{
float x;
float y;
Vec2f operator+(const Vec2f& other) const
{
Vec2f result;
result.x = x + other.x;
result.y = y + other.y;
return result;
}
};
EDIT 2:
RIJIK asks in comment:
Also i wonder if there are some tricks to make the functions not to be so repetetive. I mean if i now want to use an operator i have to make a function for each operator even if there is no big difference between the functions besides the operator which is used. How do you approach in implementing calculations or many operators?
So one thing you can do is use another operators in operator. Something like you can change subtraction to addition, by simply negate second number:
a - b becomes a + (-b)
Of course you need negation operator first in your struct to do that. Example code:
struct Vec2f
{
float x;
float y;
Vec2f operator+(const Vec2f& other) const
{
Vec2f result;
result.x = x + other.x;
result.y = y + other.y;
return result;
}
Vec2f operator-() const
{
Vec2f result;
result.x = -x;
result.y = -y;
return result;
}
// we use two operators from above to define this
Vec2f operator-(const Vec2f& other) const
{
return (*this + (-other));
}
};
One nice thing about this is that if you change addition for example than you don't need to change subtraction. It is changed automatically.
And as reply to this:
But i don't understand why i should make the functions constant.
Because then you can use this function with constant variables. For example:
const Vec2f screenSize = { 800.0f, 600.0f };
const Vec2f boxSize = { 100.0f, 200.0f };
const Vec2f sub = screenSize - boxSize;
I am using here also curly braces initialization, cause you don't define any constructor.

returning a reference vs the type

I was looking over some code, in a textbook and they wrote:
Vector3 &operator =(const Vector3 &a) {
x = a.x; y = a.y; z = a.z;
return *this;
}
Does the following code produce the same, returning the type, not a reference to it(they both run):
Vector3 operator =(const Vector3 &a) {
x = a.x; y = a.y; z = a.z;
return *this;
}
my question: what is the difference between the two?
thanks
daniel
Vector3 a, b;
(a = b).x = 3;
In this code, a.x should end up with the value of 3. In the second example you give, that won't happen.
Vector3 b(1,2,3);
Vector3 a;
(a = b).x += 2.0;
Print(a.x);
If you use operator returning refernce, above code should print 3.0
In case of operator returning value it would print 1.0