C++ Member Function Cannot Change Private Field [duplicate] - c++

This question already has an answer here:
About c++11 range for loops and iterators
(1 answer)
Closed 7 years ago.
OH! I found the problem. As I said at end, it was a simple problem.
In for loop, i iterated wiht copy of "Particle"s. I updated them but the operation does not affect the original values that stored in vector.
For requests about solution one can access the particle objects using 3 major ways.
lvalue-ref object way:
for (auto& p: particles)
...
Or by iterators:
for (auto it=particles.begin(); i<particles.end();++it)
...
Or by plain indexes:
for (size_t i=0; i<particles.size(); ++i)
...
For ones that curious about code, you may look below:
If I am not missing something very obvious, I encountered with a really strange problem.
To simplify the problem, I have a class named "Particle", which has a function called "update". Particle class has some private variables like position, velocity etc. And update function is supposed to make some calculations and add proper values to that private variables. But, that simply does not work.
Actually, I am sceptical about the type of that variables which is a class written by me, "Vector2".
To add values to variables, I've used the "+=" operator, and I think I implemented them correctly(?) in my Vector2 class.
To clarify situation, IMHO, it is better to give some code:
This is my Vector2.h :
namespace sim {
#include <ostream>
#include <cmath>
using namespace std;
struct Vector2 {
double x, y;
Vector2& operator+=(const Vector2& rhs) {
this->x += rhs.x;
this->y += rhs.y;
cout << "op+=" << endl;
return *this;
}
Vector2& operator*=(double k) {
x *= k;
y *= k;
cout << "op*=" << endl;
return *this;
}
friend ostream& operator<<(ostream& os, const Vector2& v2);
friend Vector2 operator+(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator-(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator*(Vector2 lhs, double k);
friend Vector2 operator*(double k, Vector2 rhs);
};
ostream& operator<<(ostream& os, const Vector2& v2) {
os << "[ " << v2.x << "; " << v2.y << " ]";
return os;
}
Vector2 operator+(Vector2 lhs, const Vector2& rhs) {
lhs += rhs;
cout << "op+" << endl;
return lhs;
}
Vector2 operator*(Vector2 lhs, double k) {
lhs *= k;
cout << "op*" << endl;
return lhs;
}
(removed some unrelated parts like constructor)
And this is Particle class:
class Particle {
private:
Vector2 pos;
Vector2 vel;
Vector2 acc;
double rad;
SDL_Color clr;
public:
Particle(
Vector2 _p,
Vector2 _v,
Vector2 _a,
double _r = 10.0,
SDL_Color _c = { 255, 255, 255, 255 }) {
pos = _p;
vel = _v;
acc = _a;
rad = _r;
clr = _c;
}
Vector2& move_particle(Vector2 move_by) {
return (pos += move_by);
}
void update(double dt) {
this->vel += acc * dt;
this->pos += vel * dt;
cout << "update " << pos << vel << acc << endl;
}
void render(SDL_Renderer* renderer) {
// TODO: this was supposed to be a circle, but, who cares? ;)
SDL_Rect r = { int(pos.x), int(pos.y), int(rad), int(rad) };
SDL_RenderFillRect(renderer, &r);
cout << "render" << endl;
}
};
And the result: update does not update.
How do I know (guess) my overloads DOES work?
For 3 Vector2 objects, I can do any kind of operation I defined correctly.
And the results are just what they supposed to be. (Or, maybe not?)
But debugging update function roughly brings me to the point that actually += operator works for one time, and not again BUT this behaviour is showing itself only in update function.
And I know, this will be such a simple mistake that I possibly feel ashamed (just kidding).
Oh, and the main code of course:
int main() {
SDL_Init(SDL_INIT_EVERYTHING);
auto window = SDL_CreateWindow("My Very First Particle Simulation", -1, -1,
1024, 768, SDL_WINDOW_SHOWN);
auto renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
const Vector2 g(0.0, 9.8);
double dt = 0.1;
std::vector<Particle> particles;
bool quit = false;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
quit = true;
break;
case SDL_MOUSEBUTTONUP:
particles.emplace_back(Vector2(event.button.x, event.button.y), Vector2(1.0, 0.0), g);
break;
default:
break;
}
SDL_RenderClear(renderer);
for (auto p : particles) {
p.update(dt);
p.render(renderer);
}
SDL_RenderPresent(renderer);
}
}
}

Some comments on your code,
you can just change these to be member functions
friend Vector2 operator+(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator-(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator*(Vector2 lhs, double k);
friend Vector2 operator*(double k, Vector2 lhs);
as in
Vector2 operator+(const Vector2& rhs);
Vector2 operator-(const Vector2& rhs);
Vector2 operator*(const double k);
friend Vector2 operator*(const double k, Vector2 lhs);
In them copy this to a new Vector2 and then update the value and return. The fourth function is kept as friend so that you can have something like double*Vector2 while the third one takes care of Vector2*double
Any operation that has Vector2 as the left operand can be done as a member function.

I can see that these two operators are taking their first args by value. Change them so the take their args by reference.
Vector2 operator+(Vector2 lhs, const Vector2& rhs) { // lhs should be a const reference
lhs += rhs;
cout << "op+" << endl;
return lhs;
}
Vector2 operator*(Vector2 lhs, double k) { // lhs should be a const reference
lhs *= k;
cout << "op*" << endl;
return lhs;
}
EDIT:
Also these functions should take their class args as const referenecs:
friend Vector2 operator+(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator-(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator*(Vector2 lhs, double k);
friend Vector2 operator*(double k, Vector2 rhs);

Related

C++ Angle between two vectors with acos

I'm trying to get this code to work and it gives out angles but not the right ones though, they don't add up to 180° and I can't find the problem. I've implemented a Vector2 struct which resembles a two-dimensional Vector and I have been trying to define the ^ operator for it as the function to give the angles between the two vectors.
Thanks for the help in advance!
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
struct Vector2 {
double x, y;
};
ostream& operator<<(ostream& out, const Vector2& w){
cout << '[' << w.x << " , " << w.y << ']';
return out;
}
double operator*(const Vector2& a, const Vector2& b){
double w = a.x*b.x + a.y*b.y;
return w;
}
double absc(const Vector2& d) {
return sqrt(d*d);
}
constexpr Vector2 operator+(const Vector2& a, const Vector2& b){
Vector2 y{a.x+b.x, a.y+a.y};
return y;
}
constexpr Vector2 operator-(const Vector2& a,const Vector2& b){
Vector2 z{a.x-b.x, a.y-b.y};
return z;
}
double operator^(const Vector2& a,const Vector2& b){
double n = (absc(a))*(absc(b));
double c = acos((a*b)/n);
return c;
}
int main(){
Vector2 a = {1.0, 1.0};
Vector2 b = {4.0, 7.0};
Vector2 c = {-2.0, 5.0};
double d =c^b;
double e = a^c;
double f = a^b;
auto grad = [](double rad) { return rad * (45./atan(1.0)); };
cout<<"Angle Alpha: "<<grad(c^b)<<"rad "<<d<<"\n";
cout<<"Angle Beta: "<<grad(a^c)<<"rad "<<e<<"\n";
cout<<"Angle Gamma: "<<grad(a^b)<<"rad "<<f<<"\n";
return EXIT_SUCCESS;
}
You are not comparing the right angles, try this instead (create the vectors from the points you have):
double d = (a-c)^(a-b);
double e = (b-a)^(b-c);
double f = (c-b)^(c-a);
auto grad = [](double rad) { return rad * (45./atan(1.0)); };
cout<<"Angle Alpha: "<<grad((a-c)^(a-b))<<"rad "<<d;
cout<<"\nAngle Beta: "<<grad((b-a)^(b-c))<<"rad "<<e;
cout<<"\nAngle Gamma: "<<grad((c-a)^(c-b))<<"rad "<<f;
And now you have 180° or pi.

Overloading issue

I'm trying to create a set of classes in order to handle complex numbers. I've seen that there is already a set of classes for the complex numbers, but because I'm learning C++ I thought it was a good idea to create a basic implementation. The problem comes up when I tried to overload the operator "/". I got a segfault and I can't understand if the problem is my implementation of the division:
complex.hpp :
#include <iostream>
#include <cstdlib>
class Complex {
float real;
float imm;
public:
Complex(float new_real = 0,float new_imm = 0) {this->real = new_real;this->imm = new_imm;}
void set(float new_real,float new_imm) {this->real = new_real; this->imm = new_imm;}
float get_real(void) const { return this->real;}
float get_imm(void) const { return this->imm;}
Complex conj(void) const {Complex tmp; tmp.set(this->real,-1.0 * this->imm); return tmp;}
friend std::ostream& operator<<(std::ostream& os, const Complex& cpx) {os << "Real: " << cpx.real << " Imm: " << cpx.imm << std::endl; return os; }
friend Complex operator*(const Complex& lhs,const Complex& rhs);
friend Complex operator+(const Complex& lhs,const Complex& rhs);
friend Complex operator+(const Complex& lhs,const float& rhs);
};
complex.cpp:
#include "complex.hpp"
Complex operator*(const Complex& lhs,const Complex& rhs)
{
float real_part = (lhs.real * rhs.real) - ( lhs.imm * rhs.imm);
float imm_part = (lhs.real * rhs.imm) + ( lhs.imm * rhs.real);
Complex result;
result.set(real_part,imm_part);
return result;
}
Complex operator+(const Complex& lhs,const Complex& rhs)
{
float real_part = lhs.real + rhs.real;
float imm_part = lhs.imm + rhs.imm;
Complex result;
result.set(real_part,imm_part);
return result;
}
Complex operator+(const Complex& lhs,const float& rhs)
{
float real_part = lhs.real + rhs;
float imm_part = lhs.imm;
Complex result;
result.set(real_part,imm_part);
return result;
}
Complex operator/(const Complex& lhs,const Complex& rhs)
{
Complex numerator(0,0);
numerator = rhs * rhs.conj();
Complex denominator(0,0);
denominator = lhs * rhs.conj();
Complex result;
float real_numerator = numerator.get_real();
result = denominator / real_numerator;
return result;
}
Complex operator/(const Complex& lhs,const float& rhs)
{
float real_part = lhs.get_real() / rhs;
float imm_part = lhs.get_imm() / rhs;
Complex result;
result.set(real_part,imm_part);
return result;
}
The whole idea of the division between 2 complex is to multiply the numerator and denominator for the conjugate of the numerator in order to have only a real number on the numerator. Just to make it clear :
(a + ib) / (c + id) = ((a + ib) / (c + id)) * ((c - id) / (c - id)) = ((a + ib) * (c - id)) / (c^2 + d^2)
Now when I try to do this:
main.cpp :
int main(int argc, char *argv[])
{
Complex x(4,8);
Complex y(3,7);
Complex result = x / y;
result = x / 6;
return 0;
}
I got this segfault, which I don't understand:
(gdb) break main
Breakpoint 2 at 0x401c56: file equalization_main.cpp, line 49.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
`/home/campiets/workspace/frontend/dfe_equalizer_fe/dev/view/src_c/test' has changed; re-reading symbols.
Starting program: /home/campiets/workspace/frontend/dfe_equalizer_fe/dev/view/src_c/test
Breakpoint 2, main (argc=1, argv=0x7fffffffbf08) at equalization_main.cpp:49
49 Complex x(4,8);
(gdb) n
50 Complex y(3,7);
(gdb) n
51 Complex result = x / y;
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401e64 in Complex::Complex (this=<error reading variable: Cannot access memory at address 0x7fffff3feff8>, new_real=<error reading variable: Cannot access memory at address 0x7fffff3feff4>,
new_imm=<error reading variable: Cannot access memory at address 0x7fffff3feff0>) at complex.hpp:38
38 Complex(float new_real = 0,float new_imm = 0) {this->real = new_real; this->imm = new_imm;}
Any ideas ?
Complex operator/(const Complex& lhs,const Complex& rhs)
{
...
Complex denominator...;
...
float real_numerator = ...;
result = denominator / real_numerator;
...
}
That's infinite recursion.
Since the compiler hasn't seen operator/(const Complex &lhs, const float &rhs), it converts the float argument to Complex and hence you get recursion.
The simplest solution is to declare or define operator/(const Complex &lhs, const float &rhs) before operator/(const Complex &lhs, const Complex &rhs).
My preference would be to implement the operators as class members, though. That yields simpler source code and solves the problem too.
The function
Complex operator/(const Complex& lhs,const Complex& rhs) { ... }
causes stack overflow since the line
result = denominator / real_numerator;
ends up being interpreted as:
result = denominator / Complex(real_numerator);
You can resolve that problem by defining or declaring
Complex operator/(const Complex& lhs, const float& rhs)
before it.
If you change your code to use:
Complex operator/(const Complex& lhs,const float& rhs)
{
return Complex(lhs.get_real()/rhs, lhs.get_imm()/rhs);
}
Complex operator/(const Complex& lhs,const Complex& rhs)
{
...
}
your program will work ok.
A suggestion for simplifying the above operator/ function.
If you add the following member function
float magnitude_square() const { return (real*real + imm*imm); }
then you can use
Complex operator/(const Complex& lhs,const Complex& rhs)
{
return (lhs * rhs.conj())/rhs.magnitude_square());
}

Overloading operator *

I have a vector3 class which i need to implement different multiplication options ( so i overloaded the operator *) depending of the types that im multiplying.
The problem is that in the last one i get the error:
Description Resource Path Location Type
ambiguating new declaration of 'Pang::vector3 Pang::operator*(const Pang::vector3&, const Pang::vector3&)' vector3.h /PangGame/src line 130
C/C++ Problem
But i have only one operator overloaded that returns vector and muyltiplies two vectors.
Hope you can help ( just to clarify the class vector 3 has threee double numbers ) ex: vector3(double x, double y, double z); )
friend vector3 operator* (const double& number, const vector3& vector)
{
vector3 result;
result.x = number*vector.x;
result.y = number*vector.y;
result.z = number*vector.z;
return result;
}
friend vector3 operator* (const vector3& vector, const double& number)
{
vector3 result;
result.x = number*vector.x;
result.y = number*vector.y;
result.z = number*vector.z;
return result;
}
//Scalar product: If a = a1i + a2j + a3k and b = b1i + b2j + b3k then
// a · b = a1*b1 + a2*b2 + a3*b3
friend double operator* (const vector3& vector1, const vector3& vector2)
{
double result;
result= (vector1.x)*(vector2.x)+(vector1.y)*(vector2.y) + (vector1.z)*(vector2.z);
return result;
}
/* Product: Vector x Vector
* Example: The cross product of a = (2,3,4) and b = (5,6,7)
cx = aybz - azby = 3×7 - 4×6 = -3
cy = azbx - axbz = 4×5 - 2×7 = 6
cz = axby - aybx = 2×6 - 3×5 = -3
Answer: a × b = (-3,6,-3)*/
friend vector3 operator* (const vector3& vector,const vector3& vector2)
{
vector3 result;
result.x = (vector.y)*(vector2.z) - (vector.z)*(vector2.y);
result.y = (vector.z)*(vector2.x) - (vector.x)*(vector2.z);
result.z = (vector.x)*(vector2.y) - (vector.y)*(vector2.x);
return result;
}
The problem is that you are trying to overload operator* based on the return type:
double operator* (const vector3& vector1, const vector3& vector2)
vector3 operator* (const vector3& vector1, const vector3& vector2)
This is not allowed because overload resolution takes into account the function signature, which does not include the return type:
3.19 signature [defns.signature]
⟨function⟩ name, parameter-type-list, and enclosing namespace (if any)
One possible solution, if you do want your operator* to possibly yield either a double or another vector3, you can return a proxy type that is convertible to these types:
struct vector3_multiplication_proxy {
vector3 lhs, rhs;
operator double() { return 0; /* Your inner product calculation here */ }
operator vector3() { return {}; /* Your cross product calculation here */ }
};
vector3_multiplication_proxy operator* (const vector3& lhs, const vector3& rhs) {
return {lhs, rhs};
}
This does have lifetime pitfalls and may delay calculation depending on how you use it, so it may or may not be a good idea. In your particular case, it's probably a bad idea, because the inner and cross products are different things and should probably be denoted by different syntax.

istream extraction values with formatted string

I have this formatted string in an istream.
(5, -4)
Let say :
open parenthesis
an integer number
comma and space
another integer number
close parenthesis
I would like to know what is the best approach to extract both integers and validate the string formatting.
This is in a class like this :
class MyPoint
{
public:
MyPoint() = default;
~MyPoint() = default;
...
friend ostream & operator>>(ostream & lhs, MyPoint const & rhs);
...
private:
int x, y;
};
ostream & operator>>(ostream & lhs, MyPoint const & rhs) {
// ???
}
Many thanks to all.
Here is my header file
#ifndef MYPOINT_H
#define MYPOINT_H
#include <iostream>
using namespace std;
class MyPoint
{
public:
MyPoint() : mX{ 0 }, mY{ 0 } { ; }
MyPoint(int x, int y) : mX{ x }, mY{ y } { ; }
~MyPoint() = default;
int x() const { return mX; }
int y() const { return mY; }
void setX(int x) { mX = x; }
void setY(int y) { mY = y; }
MyPoint operator-() const { return MyPoint(-mX, mY); }
MyPoint operator+(MyPoint rhs) const { rhs.mX += mX; rhs.mY += mY; return rhs; }
MyPoint operator-(MyPoint rhs) const { rhs.mX = mX - rhs.mX; rhs.mY = mY - rhs.mY; return rhs; }
MyPoint operator*(MyPoint rhs) const { rhs.mX *= mX; rhs.mY *= mY; return rhs; }
MyPoint operator/(MyPoint rhs) const { rhs.mX = mX / rhs.mX; rhs.mY = mY / rhs.mY; return rhs; }
MyPoint operator%(MyPoint rhs) const { rhs.mX = mX % rhs.mX; rhs.mY = mY % rhs.mY; return rhs; }
friend MyPoint operator+(int lhs, MyPoint const & rhs);
friend MyPoint operator-(int lhs, MyPoint const & rhs);
friend MyPoint operator*(int lhs, MyPoint const & rhs);
friend MyPoint operator/(int lhs, MyPoint const & rhs);
friend MyPoint operator%(int lhs, MyPoint const & rhs);
friend ostream & operator<<(ostream & lhs, MyPoint const & rhs);
friend istream & operator>>(istream & lhs, MyPoint & rhs);
private:
int mX, mY;
};
#endif //MYPOINT_H
And here my source file
#include "MyPoint.h"
MyPoint operator+(int lhs, MyPoint const & rhs) {
return MyPoint(lhs + rhs.mX, lhs + rhs.mY);
}
MyPoint operator-(int lhs, MyPoint const & rhs) {
return MyPoint(lhs - rhs.mX, lhs - rhs.mY);
}
MyPoint operator*(int lhs, MyPoint const & rhs) {
return MyPoint(lhs * rhs.mX, lhs * rhs.mY);
}
MyPoint operator/(int lhs, MyPoint const & rhs) {
return MyPoint(lhs / rhs.mX, lhs / rhs.mY);
}
MyPoint operator%(int lhs, MyPoint const & rhs) {
return MyPoint(lhs % rhs.mX, lhs % rhs.mY);
}
ostream & operator<<(ostream & lhs, MyPoint const & rhs) {
return lhs << "(" << rhs.mX << "," << rhs.mY << ")";
}
istream & operator >> (istream & lhs, MyPoint & rhs) {
return lhs >> "(" >> rhs.mX >> "," >> rhs.mY >> ")"; // HERE is the compiling error
}
And finally, the tests in the main
MyPoint p1, p2(2, -2);
cout << p1 << endl;
cout << p2 << endl;
With this file, I got this error :
Error C2679 binary '>>': no operator found which takes a right-hand operand of type 'const char [2]' (or there is no acceptable conversion)
For situations like this, I've often found it handy to define an overload of operator>> to read a predefined string from a stream:
std::istream &operator>>(std::istream &is, char const *pat) {
char ch;
while (isspace(static_cast<unsigned char>(is.peek())))
is.get(ch);
while (*pat && is && *pat == is.peek() && is.get(ch)) {
++pat;
}
// if we didn't reach the end of the pattern, matching failed (mismatch, premature EOF, etc.)
if (*pat) {
is.setstate(std::ios::failbit);
}
return is;
}
With this, reading your format might look something like this:
istream & operator>>(istream & lhs, MyPoint & rhs) {
return lhs >> "(" >> rhs.x >> "," >> rhs.y >> ")";
}
This will do like most typical overloads and set the stream's fail bit if the pattern you've given isn't matched. As it stands now, each string in the input can be preceded by arbitrary white space (just like conversions for numbers and such).
There is technically a minor bug here: as it stands right now, this uses the global locale's definition of whitespace. To be really correct, it should probably use the definition provided in the locale associated with the input stream.
Also note that I had to change your definition of operator>> bit; in the question it looks like an overload of operator<<, with just those two characters changed to get operator>> instead.
For a quick example:
#include <iostream>
std::istream &operator>>(std::istream &is, char const *pat) {
// implementation above
}
class Point {
int x, y;
friend std::istream &operator>>(std::istream &is, Point &p) {
return is >> "(" >> p.x >>"," >> p.y >> ")";
}
friend std::ostream &operator<<(std::ostream &os, Point const &p) {
return os << "(" << p.x <<", " << p.y << ")";
}
};
int main() {
Point p;
std::cout << "Please enter a point: ";
std::cin >> p;
std::cout << "Thanks. Point: " << p << '\n';
}
Tested with VC++ 2013, VC++ 2015, and g++ 6.1 (but this isn't pushing the limits of compilers at all, so I'd expect it to work fine even with compilers so old they're horribly broken in general (e.g., gcc 2.x or VC++ 6.0).

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.