I am trying, just for learning, to make a Vector class with a derived Vector3 class. The first Vector class, has a double* v; pointer for the array and some [] operators for easier data access, and Vector3 also has x, y, z pointers.
The important parts of the classes are like:
class Vector{
protected:
double* v;
int size_;
public:
[ ... a lot of stuff ... ]
double & operator [](int i);
}
class Vector3 : public Vector{
public:
double* x; //Access to v[0]
double* y; //Access to v[1]
double* z; //Access to v[2]
Vector3();
Vector3(double,double,double);
};
So my intention is to make a code like this work:
//You can create a Vector3 and access with x, y, z values:
Vector3 v3 = Vector3(10,9,8);
cout << "Testing v3.x -- v3.y -- v3.z" << endl;
cout << v3.x << " -- " << v3.y << " -- " << v3.z << endl;
//And also change its values
v3.x = 5;
v3.y = 1;
v3.z = 6;
//Now, the two following couts should print the same:
cout << "Testing v3.x -- v3.y -- v3.z and v3[0] -- v3[1] -- v3[2]" << endl;
cout << v3.x << " -- " << v3.y << " -- " << v3.z << endl;
cout << v3[0]<< " -- " << v3[1]<< " -- " << v3[2]<< endl;
And my question is:
Is it possible to do this without modifying that last code?
I know I can easily make this work changing the v3.x for v3.x[0] or something like that but I want it to be more intuitive.
If you do not need operator= for Vector3 class, you could change pointers to references.
class Vector3 : public Vector{
public:
double& x; //Access to v[0]
double& y; //Access to v[1]
double& z; //Access to v[2]
Vector3();
Vector3(double,double,double);
};
Related
Let's say I have a component Position. This component has only one data, its... position. So it could be defined as this:
struct Position
{
Vector2 value;
};
But it's really redondant in access like entity.getComponent<Position>.value = {x, y};so I end up doing like so:
struct Position : Vector2
{
};
Is there any downside of doing this (syntacticly speaking) or some deviance related to the hypotetic ECS holy bible?
This solution is not canonical, but you can overload the "->" operator in order to access the fields of the child structure, but then you will have to take this into account if you pass Position by pointer to any functions. It is better to pass Position always by reference, then there will be no ambiguity. Operators "." and "::" cannot be overloaded, so it will not be possible to overload the behavior of p.x or p::x.
Here is an example code:
#include <iostream>
struct Vector2
{
float x = 0, y = 0;
};
struct Position
{
Vector2* const operator ->()
{
return &value;
}
Vector2 value;
};
int main()
{
Position p;
p->x = 1;
p->y = 2;
std::cout << p.value.x << " " << p.value.y << std::endl; // prints "1 2"
Position& pref = p;
pref->x = 3;
pref->y = 4;
std::cout << p.value.x << " " << p.value.y << std::endl; // prints "3 4"
Position* pp = &p;
(*pp)->x = 5;
(*pp)->y = 6;
std::cout << p.value.x << " " << p.value.y << std::endl; // prints "5 6"
return 0;
}
So basically I created two classes for two vectors and got there norms. How would I approach using both classes to find the distance between both vectors in my main function ? I know I can use the friend function but we have not been taught that in class so I have to use the scope :: operator and constructor and destructors. I been trying different things but nothing works any ideas ? I am fairly new to c++.
#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
class Vector {
private:
float x;
float y;
float z;
public:
Vector(float xaxis, float yaxis, float zaxis)
{
x = xaxis;
y = yaxis;
z = zaxis;
}
float getx() { return x; }
float gety() { return y; }
float getz() { return z; }
float normVector()
{
float result = sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
return result;
}
};
class Vectortwo {
private:
float x;
float y;
float z;
public:
Vectortwo(float xaxis, float yaxis, float zaxis)
{
x = xaxis;
y = yaxis;
z = zaxis;
}
float getx() { return x; }
float gety() { return y; }
float getz() { return z; }
float normVectortwo()
{
float result = sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
return result;
}
};
int main()
{
Vector v(2, 2, 2);
v.getx();
v.gety();
v.getz();
v.normVector();
cout << " X axis" << v.getx() << endl;
cout << " Y axis" << v.gety() << endl;
cout << " Z axis" << v.getz() << endl;
cout << " The norm of our first vector " << v.normVector() << endl;
Vectortwo b(3, 3, 3);
b.getx();
b.gety();
b.getz();
b.normVectortwo();
cout << " X axis" << b.getx() << endl;
cout << " Y axis" << b.gety() << endl;
cout << " Z axis" << b.getz() << endl;
cout << " The norm of our first vector " << b.normVectortwo() << endl;
return 0;
}
I know I can use the friend function but we have not been taught that in class [...]
You can always use getx(), gety() and getz() directly to calculate the distance. Since this gets a bit tiresome to write more than once you can write a little function that wraps the calculation:
float distance(Vector v1, Vectortwo v2)
{
return sqrt(
pow(v1.getx() - v2.getx(), 2)
+ pow(v1.gety() - v2.gety(), 2)
+ pow(v1.getz() - v2.getz(), 2)
);
}
It has to be declared before main() (but after Vector and Vectortwo) and could be used like this:
cout << "The distance is " << distance(v, b) << " units." << endl;
Since you somehow declared to vector classes Vector and Vectortwo that are basically identical (apart from the name), you can also just remove Vectortwo and use Vector for both instances, v and b. That would simplify the code and both parameters of the distance() function could be of type Vector.
I'm Confused about a topic regarding operator overloading. See the following code:
#include <iostream>;
class Vectors {
public:
int x, y;
Vectors() {};
Vectors(int a,int b) {
x = a, y = b;
}
Vectors operator+(Vectors aso) {
Vectors brandNew;
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
brandNew.x = brandNew.x + aso.x;
brandNew.y = brandNew.y + aso.y;
return (brandNew);
};
};
int main() {
Vectors v1(2,3);
Vectors v2(4,5);
Vectors v3;
v3 = v1 + v2;
std::cout << "Vector V3 X : " << v3.x << std::endl;
std::cout << "VECTOR V3 Y : " << v3.y << std::endl;
}
When I print aso.x, it y gives me 4 and 5. What I want to do is add both v1 and v2; meaning the x of v1 and v2, and the y of v1 and v2. Then, pass it into a Vectors object and return that object.
How do I accomplish that, given what I have above?
You probably meant
Vectors operator+(const Vectors& aso) {
Vectors brandNew;
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
brandNew.x = x + aso.x;
brandNew.y = y + aso.y;
return (brandNew);
};
or
Vectors operator+(const Vectors& aso) {
Vectors brandNew(x + aso.x, y + aso.y);
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
return (brandNew);
};
As from your comment
But about if there were three.
Chain the operators like
int main() {
Vectors v1(2,3);
Vectors v2(4,5);
Vectors v3(7,11);
Vectors v4;
v4 = v1 + v2 + v3;
std::cout << "Vector V4 X : " << v4.x << std::endl;
std::cout << "Vector V4 X : " << v4.y << std::endl;
}
See Live Demo
You can also use external operator+ :
class Vectors {
public:
int x, y;
Vectors() {};
Vectors(int a,int b) {
x = a, y = b;
}
friend Vectors operator+(const Vectors& v1, const Vectors& v2);
};
Vectors operator+(const Vectors& v1, const Vectors& v2) {
Vectors brandNew;
brandNew.x = v1.x + v2.x;
brandNew.y = v1.y + v2.y;
return (brandNew);
};
int main() {
Vectors v1(2,3);
Vectors v2(4,5);
Vectors v3;
v3 = v1 + v2;
std::cout << "Vector V3 X : " << v3.x << std::endl;
std::cout << "VECTOR V3 Y : " << v3.y << std::endl;
}
You haven't initialized the x and y members of brandNew. You'll get random results.
Vectors operator+(Vectors aso) {
Vectors brandNew;
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
brandNew.x = x + aso.x;
brandNew.y = y + aso.y;
return (brandNew);
};
Your code creates the new Vectors object brandNew and then adds the values of it which are initialised to 0 to the values inside the Vectors object you passed in instead of the values in the current object. Which is why when you add v1 tov2 the result has the same values as those inside v2.
Replace
brandNew.x = brandNew.x + aso.x;
brandNew.y = brandNew.y + aso.y;
with
brandNew.x = x + aso.x;
brandNew.y = y + aso.y;
The correct definition of +operator is the following:
Vectors &operator+(const Vectors& aso)
{
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
x = x + aso.x;
y = y + aso.y;
return (*this);
}
above code does not need temporary variable and also does not do unnecessary copy of parameters as is passed by reference.
I am having issues displaying coordinates that are read into a class. This is my first time using classes so please be understanding!
Here is what I have so far:
#include <iostream>
using namespace std;
class Vector{
private:
float x;
float y;
public:
Vector(float f1, float f2)
{
x=f1;
y=f2;
}
Vector(){}
float display()
{
Vector v;
cout << "(" << v.x << "," << v.y << ")" << endl;
return 0;
}
};
int main()
{
Vector v1(0.5, 0.5);
cout << "v1 ";
v1.display();
system("pause");
return 0;
}
It prints
v1 (-1.07374e+008,-1.07374e+008)
Your problem is that you are not printing out the coordinates of the Vector you created in main() but a default created one in your function. Instead of
float display()
{
Vector v;
cout << "(" << v.x << "," << v.y << ")" << endl;
return 0;
}
You need
float display()
{
//Vector v; remove this
cout << "(" << x << "," << y << ")" << endl;
// no v.x no v.y
return 0;
}
I suggest you change the default constructor to
Vector() : x(0), y(0) {}
So it would have printed
v1 (0,0)
You should also change
Vector(float f1, float f2)
{
x=f1;
y=f2;
}
To
Vector(float f1, float f2) : x(f1), y(f2) {}
As it is a good habit to get into. This can save resources and CPU cycles when dealing with non POD types. For more information see Why should I prefer to use member initialization list?
the Vector v; line is a mistake. You are basically creating a new uninitialized vector instead of crating your own instance.
one correction would be:
int display()
{
cout << "(" << x << "," << y << ")" << endl;
return 0;
}
since x and y are member of this class
double a, b, c, d, x, y;
char operation
cout << setw(6) << a << b
<< setw(3) << operation
<< setw(6) << c << d
<< " = "
<< setw(6) << x << y
<< endl;
I'm making a calculator which takes two complex numbers and adds subtracts etc. My question is how do I format my output so that 0's are not displayed.
I.E. if the input is (a+bi)(c+di) the output is a+bi * c+di = x+yi But a, b, c, d, x, y are only displayed if they are nonzero.
I know I can do it with if statements and stuff but I was hoping there's a shorter, more efficient, path.
I don't think you can avoid doing the condition and printing if non-zero somewhere.
About all you can do is wrap it up so most code doesn't need to deal with it:
class complex {
double x;
double i;
public:
// ...
friend std::ostream &operator<<(std::ostream &os, complex const &c) {
// if both parts are 0, we probably want to print *something*
if (c.x == 0.0 && c.i == 0.0)
return os << 0;
if (c.x != 0.0)
os << c.x;
if (c.i != 0.0)
os << c.i << "i";
return os;
}
};
complex a, b, c;
// ...
cout << a << operation << b << " = " c << "\n";
You'll have to add a little more if you want this to honor (for example) width/precision correctly (though for real use, you undoubtedly want to use the complex class that's already in the standard library instead).
Yes, you can do it by including <complex>
std::complex<double> com_one; // value 0 + 0i
std::complex<double> com_two(3.14); // value 3.14 + 0i
std::complex<double> com_three(1.5, 3.14) // value 1.5 + 3.14i
std::complex<double> com_four(com_two); // value is also 3.14 + 0i
Then to use arithmetic operations, you can just use
std::cout << com_one + com_two << std::endl;
std::cout << com_one - 3.14 << std::endl;
std::cout << 2.75 * com_two << std::endl;
com_one += com_three / 2.0;
Source: http://stdcxx.apache.org/doc/stdlibug/20-2.html
For checking if it's a zero check it using if, and compare it with a zero. This is the most clean technique.